add permutation and compression

This commit is contained in:
Balazs Komuves 2024-09-24 14:11:53 +02:00
parent fcc86bbc20
commit 5512db6242
8 changed files with 170 additions and 13 deletions

View File

@ -396,7 +396,7 @@ void goldilocks_poseidon2_permutation(uint64_t *state) {
// compression function: input is two 4-element vector of field elements,
// and the output is a vector of 4 field elements
void goldilocks_poseidon2_keyed_compress(uint64_t key, const uint64_t *x, const uint64_t *y, uint64_t *out) {
void goldilocks_poseidon2_keyed_compress(const uint64_t *x, const uint64_t *y, uint64_t key, uint64_t *out) {
uint64_t state[12];
for(int i=0; i<4; i++) {
state[i ] = x[i];
@ -411,7 +411,7 @@ void goldilocks_poseidon2_keyed_compress(uint64_t key, const uint64_t *x, const
}
void goldilocks_poseidon2_compress(const uint64_t *x, const uint64_t *y, uint64_t *out) {
goldilocks_poseidon2_keyed_compress(0, x, y, out);
goldilocks_poseidon2_keyed_compress(x, y, 0, out);
}
//------------------------------------------------------------------------------

View File

@ -13,20 +13,11 @@ uint64_t goldilocks_sub(uint64_t x, uint64_t y);
uint64_t goldilocks_mul(uint64_t x, uint64_t y);
uint64_t goldilocks_mul_small(uint64_t x, uint32_t y);
uint64_t goldilocks_div_by_2(uint64_t x);
uint64_t goldilocks_div_by_3(uint64_t x);
uint64_t goldilocks_div_by_4(uint64_t x);
uint64_t goldilocks_add3(uint64_t x, uint64_t y, uint64_t z);
//uint64_t goldilocks_rdc(__uint128_t x);
//------------------------------------------------------------------------------
void goldilocks_poseidon2_permutation(uint64_t *state);
void goldilocks_monolith_permutation (uint64_t *state);
void monolith_print_sbox_table();
void monolith_print_sbox_table_c_format();
void goldilocks_poseidon2_keyed_compress(const uint64_t *x, const uint64_t *y, uint64_t key, uint64_t *out);
void goldilocks_poseidon2_compress (const uint64_t *x, const uint64_t *y, uint64_t *out);
//------------------------------------------------------------------------------

14
poseidon2/compress.nim Normal file
View File

@ -0,0 +1,14 @@
import ./types
proc c_compress(a, b: var Digest, key: uint64, output: var Digest) {. header: "../cbits/goldilocks.h", importc: "goldilocks_poseidon2_keyed_compress", cdecl .}
# keyed compression function
func compress*(a, b: Digest, key: uint64 = 0) : Digest =
var x: Digest = a
var y: Digest = b
var output: Digest
c_compress(x,y,key,output)
return output

11
poseidon2/permutation.nim Normal file
View File

@ -0,0 +1,11 @@
import ./types
# the Poseidon2 permutation (mutable, in-place version)
proc permInPlace*(state: var State) {. header: "../cbits/goldilocks.h", importc: "goldilocks_poseidon2_permutation", cdecl .}
# the Poseidon2 permutation (pure version)
func perm*(state: State): State =
var tmp = state
permInPlace(tmp)
return tmp

View File

@ -26,4 +26,10 @@ type F12* = array[12, F]
type Digest* = distinct F4
type State* = distinct F12
func fromDigest* (x : Digest): F4 = return F4(x)
func fromState * (x : State): F12 = return F12(x)
func toDigest* (x : F4 ): Digest = Digest(x)
func toState* (x : F12): State = State(x)
#-------------------------------------------------------------------------------

View File

@ -0,0 +1,83 @@
import std/unittest
# import std/sequtils
import poseidon2/types
import poseidon2/compress
#-------------------------------------------------------------------------------
const refInp1: array[4,F] =
[ toF( 1'u64 )
, toF( 2'u64 )
, toF( 3'u64 )
, toF( 4'u64 )
]
const refInp2: array[4,F] =
[ toF( 5'u64 )
, toF( 6'u64 )
, toF( 7'u64 )
, toF( 8'u64 )
]
#---------------------------------------
const refOutKey0: array[4,F] =
[ toF( 0xc4a4082f411ba790'u64 )
, toF( 0x98c2ed7546c44cce'u64 )
, toF( 0xc9404f373b78c979'u64 )
, toF( 0x65d6b3c998920f59'u64 )
]
const refOutKey1: array[4,F] =
[ toF( 0xca47449a05283778'u64 )
, toF( 0x08d3ced2020391ac'u64 )
, toF( 0xda461ea45670fb12'u64 )
, toF( 0x57f2c0b6c98a05c5'u64 )
]
const refOutKey2: array[4,F] =
[ toF( 0xe6fcec96a7a7f4b0'u64 )
, toF( 0x3002a22356daa551'u64 )
, toF( 0x899e2c1075a45f3f'u64 )
, toF( 0xf07e38ccb3ade312'u64 )
]
const refOutKey3: array[4,F] =
[ toF( 0x9930cff752b046fb'u64 )
, toF( 0x41570687cadcea0b'u64 )
, toF( 0x3ac093a5a92066c7'u64 )
, toF( 0xc45c75a3911cde87'u64 )
]
#-------------------------------------------------------------------------------
suite "compression":
test "compression of [1..4] and [5..8] with key=0":
let input1 : Digest = toDigest(refInp1)
let input2 : Digest = toDigest(refInp2)
let output : Digest = compress(input1, input2)
check ( fromDigest(output) == refOutKey0 )
test "compression of [1..4] and [5..8] with key=1":
let input1 : Digest = toDigest(refInp1)
let input2 : Digest = toDigest(refInp2)
let output : Digest = compress(input1, input2, key=1)
check ( fromDigest(output) == refOutKey1 )
test "compression of [1..4] and [5..8] with key=2":
let input1 : Digest = toDigest(refInp1)
let input2 : Digest = toDigest(refInp2)
let output : Digest = compress(input1, input2, key=2)
check ( fromDigest(output) == refOutKey2 )
test "compression of [1..4] and [5..8] with key=3":
let input1 : Digest = toDigest(refInp1)
let input2 : Digest = toDigest(refInp2)
let output : Digest = compress(input1, input2, key=3)
check ( fromDigest(output) == refOutKey3 )
#-------------------------------------------------------------------------------

View File

@ -0,0 +1,50 @@
import std/unittest
# import std/sequtils
import poseidon2/types
import poseidon2/permutation
#-------------------------------------------------------------------------------
const refInp: F12 =
[ toF( 0'u64 )
, toF( 1'u64 )
, toF( 2'u64 )
, toF( 3'u64 )
, toF( 4'u64 )
, toF( 5'u64 )
, toF( 6'u64 )
, toF( 7'u64 )
, toF( 8'u64 )
, toF( 9'u64 )
, toF( 10'u64 )
, toF( 11'u64 )
]
const refOut: F12 =
[ toF( 0x01eaef96bdf1c0c1'u64 )
, toF( 0x1f0d2cc525b2540c'u64 )
, toF( 0x6282c1dfe1e0358d'u64 )
, toF( 0xe780d721f698e1e6'u64 )
, toF( 0x280c0b6f753d833b'u64 )
, toF( 0x1b942dd5023156ab'u64 )
, toF( 0x43f0df3fcccb8398'u64 )
, toF( 0xe8e8190585489025'u64 )
, toF( 0x56bdbf72f77ada22'u64 )
, toF( 0x7911c32bf9dcd705'u64 )
, toF( 0xec467926508fbe67'u64 )
, toF( 0x6a50450ddf85a6ed'u64 )
]
#-------------------------------------------------------------------------------
suite "permutation":
test "permutation of [0..11]":
var input = toState(refInp)
var output = perm(input);
check fromState(output) == refOut
#-------------------------------------------------------------------------------

View File

@ -7,5 +7,7 @@
#import ./poseidon2/testReadme
import ./poseidon2/testField
import ./poseidon2/testPermutation
import ./poseidon2/testCompress
{.warning[UnusedImport]: off.}