From e12fb0d58e315cc5a48d220f678c53cb7d276b8b Mon Sep 17 00:00:00 2001 From: Colin Nielsen Date: Thu, 20 Apr 2023 23:57:24 -0600 Subject: [PATCH] build: try merge deps --- Nargo.toml | 3 +- lib/keccak256/Nargo.toml | 5 -- src/lib.nr | 6 +-- src/secp256k1.nr | 3 +- .../src/lib.nr => src/secp256k1/keccak256.nr | 0 .../secp256k1/keccak256}/constants.nr | 0 .../secp256k1/keccak256}/padding.nr | 53 ++++++++++++------- .../secp256k1/keccak256}/permutations.nr | 45 ++++++++++------ .../secp256k1/keccak256}/permutations/chi.nr | 25 +++++++-- .../secp256k1/keccak256}/permutations/iota.nr | 27 +++++++--- .../keccak256}/permutations/rhoPi.nr | 27 +++++++--- .../keccak256}/permutations/theta.nr | 29 +++++++--- 12 files changed, 152 insertions(+), 71 deletions(-) delete mode 100644 lib/keccak256/Nargo.toml rename lib/keccak256/src/lib.nr => src/secp256k1/keccak256.nr (100%) rename {lib/keccak256/src => src/secp256k1/keccak256}/constants.nr (100%) rename {lib/keccak256/src => src/secp256k1/keccak256}/padding.nr (79%) rename {lib/keccak256/src => src/secp256k1/keccak256}/permutations.nr (68%) rename {lib/keccak256/src => src/secp256k1/keccak256}/permutations/chi.nr (84%) rename {lib/keccak256/src => src/secp256k1/keccak256}/permutations/iota.nr (84%) rename {lib/keccak256/src => src/secp256k1/keccak256}/permutations/rhoPi.nr (86%) rename {lib/keccak256/src => src/secp256k1/keccak256}/permutations/theta.nr (83%) diff --git a/Nargo.toml b/Nargo.toml index c487923..6bd90e0 100644 --- a/Nargo.toml +++ b/Nargo.toml @@ -1,6 +1,5 @@ [package] -authors = [""] +authors = ["@colinnielsen"] compiler_version = "0.4.0" [dependencies] -keccak256 = { path = "./lib/keccak256"} \ No newline at end of file diff --git a/lib/keccak256/Nargo.toml b/lib/keccak256/Nargo.toml deleted file mode 100644 index 2dc97eb..0000000 --- a/lib/keccak256/Nargo.toml +++ /dev/null @@ -1,5 +0,0 @@ -[package] -authors = [""] -compiler_version = "0.4.0" - -[dependencies] \ No newline at end of file diff --git a/src/lib.nr b/src/lib.nr index 7727215..2faf563 100644 --- a/src/lib.nr +++ b/src/lib.nr @@ -1,7 +1,5 @@ use dep::std; -use dep::keccak256; -use dep::keccak256::constants; - + mod secp256k1; fn ecrecover( @@ -23,7 +21,7 @@ fn ecrecover( // let signature = [57, 17, 112, 239, 241, 30, 64, 157, 170, 50, 85, 145, 156, 69, 226, 85, 147, 164, 10, 82, 71, 93, 42, 132, 200, 220, 161, 255, 95, 241, 211, 141, 81, 7, 150, 25, 25, 27, 162, 213, 80, 61, 12, 170, 50, 4, 154, 203, 252, 229, 119, 29, 202, 153, 50, 25, 126, 145, 245, 23, 136, 75, 29, 177]; // let hashed_message = [13, 82, 120, 60, 76, 186, 215, 235, 175, 126, 185, 67, 252, 100, 143, 82, 130, 165, 32, 112, 68, 47, 193, 141, 141, 209, 109, 219, 47, 203, 175, 102]; -// ecrecover(pub_key_x, pub_key_y, signature, hashed_message); +// let addr = ecrecover(pub_key_x, pub_key_y, signature, hashed_message); // constrain addr == 0xe5c6169ca7a4533a0b3123e29d1efdcc38e15c67; //should be 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266; // } diff --git a/src/secp256k1.nr b/src/secp256k1.nr index 122a28b..1f541e3 100644 --- a/src/secp256k1.nr +++ b/src/secp256k1.nr @@ -1,7 +1,6 @@ use dep::std; -use dep::keccak256; -use dep::keccak256::constants; +mod keccak256; mod helpers; struct PubKey { diff --git a/lib/keccak256/src/lib.nr b/src/secp256k1/keccak256.nr similarity index 100% rename from lib/keccak256/src/lib.nr rename to src/secp256k1/keccak256.nr diff --git a/lib/keccak256/src/constants.nr b/src/secp256k1/keccak256/constants.nr similarity index 100% rename from lib/keccak256/src/constants.nr rename to src/secp256k1/keccak256/constants.nr diff --git a/lib/keccak256/src/padding.nr b/src/secp256k1/keccak256/padding.nr similarity index 79% rename from lib/keccak256/src/padding.nr rename to src/secp256k1/keccak256/padding.nr index 9be2a64..ef663a6 100644 --- a/lib/keccak256/src/padding.nr +++ b/src/secp256k1/keccak256/padding.nr @@ -1,29 +1,44 @@ -use crate::constants; +// Input size related + +// The input must be at least 2 bits smaller than the block size to accommodate the padding bits. +global INPUT_SIZE: Field = 16; +// Blocks are 136 bytes. 138 * 8 = 1088 bits. +global BLOCK_SIZE: Field = 17; + +global OUTPUT_SIZE: Field = 4; + +// State size related +global LANE_LENGTH: Field = 64; +global COLUMN_LENGTH: Field = 5; +global NUM_LANES: Field = 25; + +// Misc +global NUM_ROUNDS: Field = 24; // This is a simplified implementation of the pad10*1 algorithm. // As we assume that the input length is smaller than the block size, we can ignore the potential for the padding // sequence to be spread over multiple blocks. -fn pad(input: [u64; constants::INPUT_SIZE], input_length: u64) -> [u64; constants::BLOCK_SIZE] { +fn pad(input: [u64; INPUT_SIZE], input_length: u64) -> [u64; BLOCK_SIZE] { // We require 2 bits of space after the message in order to include the padding bits. // constrain input_length < BLOCK_SIZE - 2; - let mut padded_input: [u64; constants::BLOCK_SIZE] = [0; constants::BLOCK_SIZE]; - for i in 0..constants::INPUT_SIZE { + let mut padded_input: [u64; BLOCK_SIZE] = [0; BLOCK_SIZE]; + for i in 0..INPUT_SIZE { // Caching the word from input here reduces the number of gates. let word = input[i]; - if input_length >= ((i + 1) * constants::LANE_LENGTH) as u64 { + if input_length >= ((i + 1) * LANE_LENGTH) as u64 { // The input continues past the end of the current word. // We then copy it verbatim into the padded input. padded_input[i] = word; - } else if input_length >= (i * constants::LANE_LENGTH) as u64 { + } else if input_length >= (i * LANE_LENGTH) as u64 { // The input ends in this current word. // We must then insert the first padding bit at the correct location before copying it. - // Subtracting `i * constants::LANE_LENGTH` from `input_length` shifts it into the range [0, 63] - let bit_position: Field = input_length as Field - i * constants::LANE_LENGTH; + // Subtracting `i * LANE_LENGTH` from `input_length` shifts it into the range [0, 63] + let bit_position: Field = input_length as Field - i * LANE_LENGTH; // Copy across both the input and the padding bit. padded_input[i] = checked_bit_insert(word, bit_position); @@ -33,13 +48,13 @@ fn pad(input: [u64; constants::INPUT_SIZE], input_length: u64) -> [u64; constant } }; - if input_length == (constants::INPUT_SIZE * constants::LANE_LENGTH) as u64 { + if input_length == (INPUT_SIZE * LANE_LENGTH) as u64 { // Both padding bits fall in the last word and so the first wasn't written during the for-loop. // We can then just write both bits directly now. - padded_input[constants::BLOCK_SIZE - 1] = 0x8000000000000001; + padded_input[BLOCK_SIZE - 1] = 0x8000000000000001; } else { // Place the second 1 bit of the padding in the last bit of the block. - padded_input[constants::BLOCK_SIZE - 1] = 0x0000000000000001; + padded_input[BLOCK_SIZE - 1] = 0x0000000000000001; } padded_input @@ -103,9 +118,9 @@ fn test_checked_bit_insert() { #[test] fn test_pad() { { - let input: [u64; constants::INPUT_SIZE] = [0;constants::INPUT_SIZE]; + let input: [u64; INPUT_SIZE] = [0;INPUT_SIZE]; let input_length: u64 = 0; - let expected_output: [u64; constants::BLOCK_SIZE] = [ + let expected_output: [u64; BLOCK_SIZE] = [ 0x8000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -128,9 +143,9 @@ fn test_pad() { } { - let input: [u64; constants::INPUT_SIZE] = [0;constants::INPUT_SIZE]; - let input_length: u64 = 64 * (constants::INPUT_SIZE as u64); - let expected_output: [u64; constants::BLOCK_SIZE] = [ + let input: [u64; INPUT_SIZE] = [0;INPUT_SIZE]; + let input_length: u64 = 64 * (INPUT_SIZE as u64); + let expected_output: [u64; BLOCK_SIZE] = [ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, @@ -154,10 +169,10 @@ fn test_pad() { // { // // Input extends past stated length - // let mut input: [u64; constants::INPUT_SIZE] = [0;constants::INPUT_SIZE]; - // input[constants::INPUT_SIZE - 1] = 0x0000000000000001; + // let mut input: [u64; INPUT_SIZE] = [0;INPUT_SIZE]; + // input[INPUT_SIZE - 1] = 0x0000000000000001; // let input_length: u64 = 0; - // let expected_output: [u64; constants::BLOCK_SIZE] = [ + // let expected_output: [u64; BLOCK_SIZE] = [ // 0x0000000000000000, // 0x0000000000000000, // 0x0000000000000000, diff --git a/lib/keccak256/src/permutations.nr b/src/secp256k1/keccak256/permutations.nr similarity index 68% rename from lib/keccak256/src/permutations.nr rename to src/secp256k1/keccak256/permutations.nr index 2d29597..e5ff1c9 100644 --- a/lib/keccak256/src/permutations.nr +++ b/src/secp256k1/keccak256/permutations.nr @@ -1,4 +1,19 @@ -use crate::constants; +// Input size related + +// The input must be at least 2 bits smaller than the block size to accommodate the padding bits. +global INPUT_SIZE: Field = 16; +// Blocks are 136 bytes. 138 * 8 = 1088 bits. +global BLOCK_SIZE: Field = 17; + +global OUTPUT_SIZE: Field = 4; + +// State size related +global LANE_LENGTH: Field = 64; +global COLUMN_LENGTH: Field = 5; +global NUM_LANES: Field = 25; + +// Misc +global NUM_ROUNDS: Field = 24; mod chi; mod iota; @@ -7,12 +22,12 @@ mod theta; // This is a simplified implementation of the Keccak256 absorb function where we assume the input is smaller than the // internal state size. -fn absorb(input: [u64; constants::BLOCK_SIZE]) -> [u64; constants::NUM_LANES] { - let mut state: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; +fn absorb(input: [u64; BLOCK_SIZE]) -> [u64; NUM_LANES] { + let mut state: [u64; NUM_LANES] = [0; NUM_LANES]; // We should in theory XOR the input with the internal state. However we know that X ^ 0 = X so we can just write // the input into the state. We can do this as the input is guaranteed to be smaller than the state size. - for i in 0..constants::BLOCK_SIZE { + for i in 0..BLOCK_SIZE { state[i] = input[i]; }; @@ -22,17 +37,17 @@ fn absorb(input: [u64; constants::BLOCK_SIZE]) -> [u64; constants::NUM_LANES] { state } -fn squeeze(input: [u64; constants::NUM_LANES]) -> [u64; constants::OUTPUT_SIZE] { +fn squeeze(input: [u64; NUM_LANES]) -> [u64; OUTPUT_SIZE] { - let mut result: [u64; constants::OUTPUT_SIZE] = [0; constants::OUTPUT_SIZE]; + let mut result: [u64; OUTPUT_SIZE] = [0; OUTPUT_SIZE]; - for i in 0..constants::OUTPUT_SIZE { + for i in 0..OUTPUT_SIZE { result[i] = input[i]; }; result } -fn keccakfRound(state: [u64; constants::NUM_LANES], round_number: comptime Field) -> [u64; constants::NUM_LANES] { +fn keccakfRound(state: [u64; NUM_LANES], round_number: comptime Field) -> [u64; NUM_LANES] { let state_after_theta = theta::theta(state); let state_after_rhoPi = rhoPi::rhoPi(state_after_theta); @@ -42,9 +57,9 @@ fn keccakfRound(state: [u64; constants::NUM_LANES], round_number: comptime Field new_state } -fn keccakf(input: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { +fn keccakf(input: [u64; NUM_LANES]) -> [u64; NUM_LANES] { let mut state = input; - for i in 0..constants::NUM_ROUNDS { + for i in 0..NUM_ROUNDS { state = keccakfRound(state, i); }; state @@ -52,10 +67,10 @@ fn keccakf(input: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { #[test] fn test_keccakfRound(){ - let input: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let input: [u64; NUM_LANES] = [0; NUM_LANES]; // Round 0 - let mut after_round_one: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let mut after_round_one: [u64; NUM_LANES] = [0; NUM_LANES]; after_round_one[0] = 0x0000000000000001; constrain keccakfRound(input, 0) == after_round_one; } @@ -64,10 +79,10 @@ fn test_keccakfRound(){ fn test_keccakf(){ // Test cases taken from: // https://github.com/XKCP/XKCP/blob/64404beeeb261b08a1076fe2f076e4e28dd9b040/tests/TestVectors/KeccakF-1600-IntermediateValues.txt - let input_state: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let input_state: [u64; NUM_LANES] = [0; NUM_LANES]; // Permutation 0 - let perm_zero_output: [u64; constants::NUM_LANES] = [ + let perm_zero_output: [u64; NUM_LANES] = [ 0xF1258F7940E1DDE7, 0x84D5CCF933C0478A, 0xD598261EA65AA9EE, 0xBD1547306F80494D, 0x8B284E056253D057, 0xFF97A42D7F8E6FD4, 0x90FEE5A0A44647C4, 0x8C5BDA0CD6192E76, 0xAD30A6F71B19059C, 0x30935AB7D08FFC64, 0xEB5AA93F2317D635, 0xA9A6E6260D712103, 0x81A57C16DBCF555F, 0x43B831CD0347C826, 0x01F22F1A11A5569F, @@ -77,7 +92,7 @@ fn test_keccakf(){ constrain keccakf(input_state) == perm_zero_output; // Permutation 1 - let perm_one_output: [u64; constants::NUM_LANES] = [ + let perm_one_output: [u64; NUM_LANES] = [ 0x2D5C954DF96ECB3C, 0x6A332CD07057B56D, 0x093D8D1270D76B6C, 0x8A20D9B25569D094, 0x4F9C4F99E5E7F156, 0xF957B9A2DA65FB38, 0x85773DAE1275AF0D, 0xFAF4F247C3D810F7, 0x1F1B9EE6F79A8759, 0xE4FECC0FEE98B425, 0x68CE61B6B9CE68A1, 0xDEEA66C4BA8F974F, 0x33C43D836EAFB1F5, 0xE00654042719DBD9, 0x7CF8A9F009831265, diff --git a/lib/keccak256/src/permutations/chi.nr b/src/secp256k1/keccak256/permutations/chi.nr similarity index 84% rename from lib/keccak256/src/permutations/chi.nr rename to src/secp256k1/keccak256/permutations/chi.nr index fb3ca96..9c38f7a 100644 --- a/lib/keccak256/src/permutations/chi.nr +++ b/src/secp256k1/keccak256/permutations/chi.nr @@ -1,11 +1,26 @@ -use crate::constants; +// Input size related -fn chi(state: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { +// The input must be at least 2 bits smaller than the block size to accommodate the padding bits. +global INPUT_SIZE: Field = 16; +// Blocks are 136 bytes. 138 * 8 = 1088 bits. +global BLOCK_SIZE: Field = 17; + +global OUTPUT_SIZE: Field = 4; + +// State size related +global LANE_LENGTH: Field = 64; +global COLUMN_LENGTH: Field = 5; +global NUM_LANES: Field = 25; + +// Misc +global NUM_ROUNDS: Field = 24; + +fn chi(state: [u64; NUM_LANES]) -> [u64; NUM_LANES] { let mut new_state = state; // The labelling convention for the state array is `Lane(x, y) = state[5y + x]`. // Iterate over each plane and write updated values for each lane. - for y in 0..constants::COLUMN_LENGTH { + for y in 0..COLUMN_LENGTH { new_state[5 * y + 0] = state[5 * y + 0] ^ ((!state[5 * y + 1]) & state[5 * y + 2]); new_state[5 * y + 1] = state[5 * y + 1] ^ ((!state[5 * y + 2]) & state[5 * y + 3]); new_state[5 * y + 2] = state[5 * y + 2] ^ ((!state[5 * y + 3]) & state[5 * y + 4]); @@ -22,7 +37,7 @@ fn test_chi(){ // https://github.com/XKCP/XKCP/blob/64404beeeb261b08a1076fe2f076e4e28dd9b040/tests/TestVectors/KeccakF-1600-IntermediateValues.txt // Round 0 - let round_zero_input: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let round_zero_input: [u64; NUM_LANES] = [0; NUM_LANES]; constrain chi(round_zero_input) == round_zero_input; // Round 1 @@ -43,7 +58,7 @@ fn test_chi(){ constrain chi(round_one_input) == round_one_output; // Round 2 - let round_two_input: [u64; constants::NUM_LANES] = [ + let round_two_input: [u64; NUM_LANES] = [ 0x0000700000600487, 0x18C8900002300102, 0x0030300003800101, 0x2002083081800004, 0x08800C0042C14000, 0x00041840D0000210, 0x20030210B0100002, 0x0003800003042030, 0x3191200000600200, 0x40000E20040400C0, 0x0000260020031912, 0x001C000808018180, 0x0000830C1C000042, 0x00220030010B0100, 0xC400018210100001, diff --git a/lib/keccak256/src/permutations/iota.nr b/src/secp256k1/keccak256/permutations/iota.nr similarity index 84% rename from lib/keccak256/src/permutations/iota.nr rename to src/secp256k1/keccak256/permutations/iota.nr index 40fd304..697246f 100644 --- a/lib/keccak256/src/permutations/iota.nr +++ b/src/secp256k1/keccak256/permutations/iota.nr @@ -1,8 +1,23 @@ -use crate::constants; +// Input size related -fn iota(state: [u64; constants::NUM_LANES], round_number: comptime Field) -> [u64; constants::NUM_LANES] { +// The input must be at least 2 bits smaller than the block size to accommodate the padding bits. +global INPUT_SIZE: Field = 16; +// Blocks are 136 bytes. 138 * 8 = 1088 bits. +global BLOCK_SIZE: Field = 17; + +global OUTPUT_SIZE: Field = 4; + +// State size related +global LANE_LENGTH: Field = 64; +global COLUMN_LENGTH: Field = 5; +global NUM_LANES: Field = 25; + +// Misc +global NUM_ROUNDS: Field = 24; + +fn iota(state: [u64; NUM_LANES], round_number: comptime Field) -> [u64; NUM_LANES] { // Each element of RC is a bitmap for the mask to apply to the lane. - let RC: [comptime u64; constants::NUM_ROUNDS] = [ + let RC: [comptime u64; NUM_ROUNDS] = [ 0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000, 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008A, @@ -26,7 +41,7 @@ fn test_iota(){ // https://github.com/XKCP/XKCP/blob/64404beeeb261b08a1076fe2f076e4e28dd9b040/tests/TestVectors/KeccakF-1600-IntermediateValues.txt // Round 0 - let round_zero_input: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let round_zero_input: [u64; NUM_LANES] = [0; NUM_LANES]; let round_zero_output = [ 0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000, 0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000, @@ -44,7 +59,7 @@ fn test_iota(){ 0x0000000010000400, 0x0000000000000000, 0x0000000000000400, 0x0000000010000000, 0x0000000000000000, 0x0000010000000000, 0x0000000000000000, 0x0000010000000004, 0x0000000000000000, 0x0000000000000004, ]; - let round_one_output: [u64; constants::NUM_LANES] = [ + let round_one_output: [u64; NUM_LANES] = [ 0x0000000000008083, 0x0000100000000000, 0x0000000000008000, 0x0000000000000001, 0x0000100000008000, 0x0000000000000000, 0x0000200000200000, 0x0000000000000000, 0x0000200000000000, 0x0000000000200000, 0x0000000000000002, 0x0000000000000200, 0x0000000000000000, 0x0000000000000202, 0x0000000000000000, @@ -54,7 +69,7 @@ fn test_iota(){ constrain iota(round_one_input, 1) == round_one_output; // Round 2 - let round_two_input: [u64; constants::NUM_LANES] = [ + let round_two_input: [u64; NUM_LANES] = [ 0x0030500001E00486, 0x38CA983082300106, 0x08B0340041C14101, 0x2002783081A00483, 0x10488C0040D14100, 0x00049840D3042220, 0x11932210B0700202, 0x40038E20070020F0, 0x31953040D0600010, 0x60030C30241400C2, 0x0000A50434031950, 0x003E0038090A8080, 0xC400828E0C100043, 0x0022263021081812, 0xC41C018A18108081, diff --git a/lib/keccak256/src/permutations/rhoPi.nr b/src/secp256k1/keccak256/permutations/rhoPi.nr similarity index 86% rename from lib/keccak256/src/permutations/rhoPi.nr rename to src/secp256k1/keccak256/permutations/rhoPi.nr index ef483c3..01220de 100644 --- a/lib/keccak256/src/permutations/rhoPi.nr +++ b/src/secp256k1/keccak256/permutations/rhoPi.nr @@ -1,10 +1,25 @@ -use crate::constants; +// Input size related + +// The input must be at least 2 bits smaller than the block size to accommodate the padding bits. +global INPUT_SIZE: Field = 16; +// Blocks are 136 bytes. 138 * 8 = 1088 bits. +global BLOCK_SIZE: Field = 17; + +global OUTPUT_SIZE: Field = 4; + +// State size related +global LANE_LENGTH: Field = 64; +global COLUMN_LENGTH: Field = 5; +global NUM_LANES: Field = 25; + +// Misc +global NUM_ROUNDS: Field = 24; // This function is a combination of the rho and pi functions as defined in the Keccak256 specification. // We merge these two functions as rho consists of a rotation of the bits within each lane and pi is a remapping of // the lane indices. We can then efficiently perform both of these steps simultaneously by writing the output of rho // directly into the remapped lane specified by pi. -fn rhoPi(state: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { +fn rhoPi(state: [u64; NUM_LANES]) -> [u64; NUM_LANES] { // These are precomputed pairs of indices within the state array which specify how to perform the pi mapping. // Lanes are remapped such that the lane sitting at index READ_LANE_OFFSETS[i] is remapped to WRITE_LANE_OFFSETS[i]. let READ_LANE_OFFSETS: [comptime Field; 24] = [1, 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6]; @@ -16,13 +31,13 @@ fn rhoPi(state: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { // This definition adds an additional modulo compared to the spec but makes it easier to calculate correct offsets. let T: [comptime u64; 24] = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44]; - let mut new_state: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let mut new_state: [u64; NUM_LANES] = [0; NUM_LANES]; // The center lane is unaffected by the rho and pi functions so we write it directly into the new state. new_state[0] = state[0]; // Now for the remaining lanes we write the rotated lane outputted from rho into the remapped lane specified by pi. - for i in 0..constants::NUM_LANES - 1 { + for i in 0..NUM_LANES - 1 { new_state[WRITE_LANE_OFFSETS[i]] = rotl64(state[READ_LANE_OFFSETS[i]], T[i]); }; @@ -40,7 +55,7 @@ fn test_rhoPi(){ // https://github.com/XKCP/XKCP/blob/64404beeeb261b08a1076fe2f076e4e28dd9b040/tests/TestVectors/KeccakF-1600-IntermediateValues.txt // Round 0 - let round_zero_input: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let round_zero_input: [u64; NUM_LANES] = [0; NUM_LANES]; constrain rhoPi(round_zero_input) == round_zero_input; // Round 1 @@ -61,7 +76,7 @@ fn test_rhoPi(){ constrain rhoPi(round_one_input) == round_one_output; // Round 2 - let round_two_input: [u64; constants::NUM_LANES] = [ + let round_two_input: [u64; NUM_LANES] = [ 0x0000700000600487, 0x0000130010018C89, 0x0000700020208606, 0x000021000041840D, 0x0000320030018B01, 0x0000700000608404, 0x0000230010218C89, 0x0000700020200606, 0x000001000041840C, 0x0000220030210B01, 0x0000700000608406, 0x0000030010018E89, 0x0000700020200606, 0x000021000041860E, 0x0000220030010B01, diff --git a/lib/keccak256/src/permutations/theta.nr b/src/secp256k1/keccak256/permutations/theta.nr similarity index 83% rename from lib/keccak256/src/permutations/theta.nr rename to src/secp256k1/keccak256/permutations/theta.nr index 99b1bef..0d8c249 100644 --- a/lib/keccak256/src/permutations/theta.nr +++ b/src/secp256k1/keccak256/permutations/theta.nr @@ -1,6 +1,21 @@ -use crate::constants; +// Input size related -fn theta(state: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { +// The input must be at least 2 bits smaller than the block size to accommodate the padding bits. +global INPUT_SIZE: Field = 16; +// Blocks are 136 bytes. 138 * 8 = 1088 bits. +global BLOCK_SIZE: Field = 17; + +global OUTPUT_SIZE: Field = 4; + +// State size related +global LANE_LENGTH: Field = 64; +global COLUMN_LENGTH: Field = 5; +global NUM_LANES: Field = 25; + +// Misc +global NUM_ROUNDS: Field = 24; + +fn theta(state: [u64; NUM_LANES]) -> [u64; NUM_LANES] { // The theta function works by calculating the parity of each of the columns in the state array. We store these // in the C[x, z] arrays. // C[x, z] = A[x, 0, z] ^ A[x, 1, z] ^ A[x, 2, z] ^ A[x, 3, z] ^ A[x, 4, z] @@ -18,8 +33,8 @@ fn theta(state: [u64; constants::NUM_LANES]) -> [u64; constants::NUM_LANES] { let d4: u64 = c3 ^ rotl64(c0, 1); // The labelling convention for the state array is `lane(x, y) = state[5y + x]`. - let mut new_state = [0; constants::NUM_LANES]; - for y in 0..constants::COLUMN_LENGTH { + let mut new_state = [0; NUM_LANES]; + for y in 0..COLUMN_LENGTH { new_state[5 * y + 0] = state[5 * y + 0] ^ d0; new_state[5 * y + 1] = state[5 * y + 1] ^ d1; new_state[5 * y + 2] = state[5 * y + 2] ^ d2; @@ -48,11 +63,11 @@ fn test_theta(){ // https://github.com/XKCP/XKCP/blob/64404beeeb261b08a1076fe2f076e4e28dd9b040/tests/TestVectors/KeccakF-1600-IntermediateValues.txt // Round 0 - let round_zero_input: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let round_zero_input: [u64; NUM_LANES] = [0; NUM_LANES]; constrain theta(round_zero_input) == round_zero_input; // Round 1 - let mut round_one_input: [u64; constants::NUM_LANES] = [0; constants::NUM_LANES]; + let mut round_one_input: [u64; NUM_LANES] = [0; NUM_LANES]; round_one_input[0] = 0x0000000000000001; let round_one_output = [ 0x0000000000000001,0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000002, @@ -64,7 +79,7 @@ fn test_theta(){ constrain theta(round_one_input) == round_one_output; // Round 2 - let round_two_input: [u64; constants::NUM_LANES] = [ + let round_two_input: [u64; NUM_LANES] = [ 0x0000000000008083, 0x0000100000000000, 0x0000000000008000, 0x0000000000000001, 0x0000100000008000, 0x0000000000000000, 0x0000200000200000, 0x0000000000000000, 0x0000200000000000, 0x0000000000200000, 0x0000000000000002, 0x0000000000000200, 0x0000000000000000, 0x0000000000000202, 0x0000000000000000,