diff --git a/bin/e2e/e2e.rs b/bin/e2e/e2e.rs index 4eb7657..f177076 100644 --- a/bin/e2e/e2e.rs +++ b/bin/e2e/e2e.rs @@ -147,12 +147,18 @@ async fn main() -> eyre::Result<()> { let uniqueness_check_result = serde_json::from_str::(&message_body)?; - // Check that signup id and serial id match expected values assert_eq!(uniqueness_check_result.signup_id, element.signup_id); assert_eq!(uniqueness_check_result.serial_id, next_serial_id); - // If there are matches, check that the distances match the expected values - if !uniqueness_check_result.matches.is_empty() { + // If there should be matches, check that the distances match the expected values + if !element.matched_with.is_empty() { + assert_eq!( + uniqueness_check_result.matches.len(), + element.matched_with.len(), + "Wrong number of matches for signup_id: {}", + element.signup_id + ); + for (i, distance) in uniqueness_check_result.matches.iter().enumerate() { diff --git a/bin/e2e/two_code_sequence_no_rotations.json b/bin/e2e/two_code_sequence_no_rotations.json new file mode 100644 index 0000000..de6c71d --- /dev/null +++ b/bin/e2e/two_code_sequence_no_rotations.json @@ -0,0 +1,17 @@ +[ + { + "signup_id": "0", + "iris_code": "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", + "mask_code": "//////////////////////z//////////////////////8zM///////////8z//M/////////////M/P/////P////MzMzAAADMwAP///////////////////////8zM////////////////////////////////////////////////////////////////////////////////////////////////MzMAAAAzMzP//8zP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8zMzAAAAAzMzMwAAAP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////MzMwAAAAAzMzAAAAAzMz////////////////////////////////////////////////////////////////////////////////////////////////////////////////8zMzMAAAAAADAAAAAAAAAzMzMAAAAM////////////////////////////////////////////////////////////////////////////////////////////////////////MzMzAAAAAAAAAAAAAAAAAAAAAAAAAAADMz/////////////////////////////////////////////////////////////////////////////////////////////////zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP///////////////////////////////////////////////////////////////////////////////////////////8zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP///////////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP//////////////////////////////////////////////////////////////////////////////////////zMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP/////////////////////////////////////////////////////////////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP///////////////////////////////////////////////////////////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzP/////////////////////////////////////////////////////////////////////////////////MzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzM/////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzM///////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMz/////////////////////////////////////////////////////////////////////////////zMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMz///w==", + "matched_with": [] + }, + { + "signup_id": "1", + "iris_code": "ibqIuouomyABMyAgG4mom4moIBMiITMiRXds3+32RXdk7N/+iJqgASBkVX7f+qiTASV2RX/+37qLIAF1fsm6iSAROom6IAF1dkVf//7N32RXTf7N/s3/zbogE2RV/f6ouqATMs26iJuKiZsgATIgATKJqJuJICASiiAzIkV3fN/ldlV3bM3f6qiaACATZkV+3/qIEwFkdkV//t36iyABdX7N+om6iACZMiABVXdkXf/+iJsgF0V83fqBds3boBdkX/36qLIAF17d+ombqomTIAEyIBMgAbqLibqIMgMgMldF/t6AF2RVd+zN/s26qoMgEkZFft/6gFdFdERVduzd+okiAXVs3/qIuqIAEzIiAFVXZN3++oiDIBNldX3+R2Xd3+ibIFftm6ggAVZN/7qJuyIDEyCJuqiTIBE2Tem6iBITBHZf/u6LqBMgF3dkRXbN//qboDIDdXTf9kV3XfzNd3bN37qIMgFX7N+qiooCABMxIgBFd2Td/LqIgyAzZFd1dldt393+iKoTIBu6IgF2Tbu6iCAyBVdk3+y4mqARMgNpu6gTAkV2zf/szd+6qLIAMEV2Rez926iyATJFV0V+zd3+iKB2zduogBNk3+yKiJqAAyARETJkRXds3f26iAIBMkVXdVdt3f/t/oibEyJFdt/tuom7m6oBMkVXZN/t2bqIkiATIRMgEwdF/siTIGRf/JuqACE1VXZERV/N+oEwRVdF/s39+oqgEhCbIAF1bN+qiIkyIBE0RFd3ZEVXft39uoiAATA2VXVXZN3+7f7MV0V2Td/fqLqBdX+iBXdHbezf7om6iboAEyATJFZN36iIkyBkV+zbqoABIFV0BkVXTd/s5EVX3f7N/bqbqAEwEgIBbfibqgAhF2RVd3Tf/+5FV/7M37qqoAMhMgAwV2RXfu32RVdFfs3f+6gSAWV2Vk3f/omooCIJuomoABMgEkRXzduoiRMgNFfs26qCASBVcAJFV0Vd/s3+zdu6AXXd26iZMBISiaibkyIBdFV1Vf/+3f3+zf3f7N/JuqiDITALqJMgAyAldkVXZX/N/4uoEgdldl383fqKqCACAbqJqJAyADZEX9+6iJETIDATIJugAkVd3boAJVZFXf7N/omZMgNX7duomqAwEgIgEwIkVXRVdlX93938/s/+3+zf6buoizKouoi6oAAgABF2RXV33f7JqAAXRX7d/sm6qKggAgE4maiIMgEhZE3/6oiam6iokgATIEZEX/26ASRXV13+zf6IiTIGR+3bqIqoshIiABZHdVd2VXdVdd/9/szf/s/u36i6qIm6ibqJuqACICIBMkV0VV3+zfqAF9/+ibqJu6iaIgIFbd24iLIDIXZF/P6om4uoqJIBICASRV/fqAF0VXdP7N/v7WRf/s/t24qKiLoCIgBXV3VX/1V3V1Xf3f7M3/7f7s/tuoioqom6ibqoAgAiAAIVd2RV/9/f7N/7mom6ARMgEyIBdk39+oigISR2Rez+qJupICASAyAgEgAgEyADZFV2R2Xf/83+3f7N7dqLqoiyAgJFV1d1V//9/3dN/s3+zd/s387P7bqIqIqoqom6qIIBIgAAAVV3V33f3+zfuJuokgEyAFV2RX7N/bqLIAEkVk/s36iboAAgMgE6iJqKoBMgARE2ZEdlVf7N/t/+zezfqJqoIiIFVVd3ZVX/3f/f7PZEV0VXZVX/3+36qKiZqKqJuqioiyAAIgABVXdk3//s37qbqIMgIgVVfu3+iam6gyABdFdF7N+IiaADIDJFfsmbqoiTIAARMiRXV0V/7f7f7s3826iboAAgVXdVd3/d3/36iqggABMkV0VVd93////ouqiqi4uoqJqgAAIiABFXdVX/7N36i6qAIAMFdd/ouqipMgEgBGRXZN3fi6mgEyACBXZPy7qIm6AgEyAkV1dFV/3/3+7N/9momiAABVV2VV//3d+qqoqgAAADIFdVdVVV39//zeiIioqLqKiqqAACIgABJFV1X/39/tupqDIBRXzbqJqoISIBMkZkV2zf3oupsBMgAgEyVk+qiIqAIBIgNVdXRVdd/9/N7f35upIgBkVXd1Xf/f2bqogAAAACAyBXVXVVVVXd/8/siZqoiKiqiqiIIiIAACBFd1///Q==", + "mask_code": "////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Mz//Mz///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////zAMwAAMwAAAAMzM///zMz/////////////////////////////////////////////////////////////////////////////////////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAzM//////////////////////////////////////////////////////////////////////////////////////////////////////M8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAADM////////////////////////////////////////////////////////////////////////////////////////////////zMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzMADP////////////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM///////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM///////////////////////////////////////////////////////////////////////////////8zMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz////////////////////////////////////////////////////////////////////////////MzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP/////////////////////////////////////////////////////////////////////////MzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz///////////////////////////////////////////////////////////////////////zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz//////////////////////////////////////////////////////////////////////MzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz///////////////////////////////MzMzMz///////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzP/////////////////////////8zMAAAAAAAAAMz////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMw==", + "matched_with": [], + "_comment": { + "distance_to_signup_id_0": 0.47833602212491355 + } + } +] diff --git a/bin/e2e/two_codes_sequence_with_rotations.json b/bin/e2e/two_codes_sequence_with_rotations.json new file mode 100644 index 0000000..c3c18ee --- /dev/null +++ b/bin/e2e/two_codes_sequence_with_rotations.json @@ -0,0 +1,19 @@ +[ + { + "signup_id": "0", + "iris_code": "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", + "mask_code": "//////////////////////z//////////////////////8zM///////////8z//M/////////////M/P/////P////MzMzAAADMwAP///////////////////////8zM////////////////////////////////////////////////////////////////////////////////////////////////MzMAAAAzMzP//8zP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8zMzAAAAAzMzMwAAAP////////////////////////////////////////////////////////////////////////////////////////////////////////////////////MzMwAAAAAzMzAAAAAzMz////////////////////////////////////////////////////////////////////////////////////////////////////////////////8zMzMAAAAAADAAAAAAAAAzMzMAAAAM////////////////////////////////////////////////////////////////////////////////////////////////////////MzMzAAAAAAAAAAAAAAAAAAAAAAAAAAADMz/////////////////////////////////////////////////////////////////////////////////////////////////zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP///////////////////////////////////////////////////////////////////////////////////////////8zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP///////////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP//////////////////////////////////////////////////////////////////////////////////////zMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP/////////////////////////////////////////////////////////////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP///////////////////////////////////////////////////////////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzP/////////////////////////////////////////////////////////////////////////////////MzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzM/////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzM///////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMz/////////////////////////////////////////////////////////////////////////////zMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMz///w==", + "matched_with": [] + }, + { + "signup_id": "1", + "iris_code": "ibqIuouomyABMyAgG4mom4moIBMiITMiRXds3+32RXdk7N/+iJqgASBkVX7f+qiTASV2RX/+37qLIAF1fsm6iSAROom6IAF1dkVf//7N32RXTf7N/s3/zbogE2RV/f6ouqATMs26iJuKiZsgATIgATKJqJuJICASiiAzIkV3fN/ldlV3bM3f6qiaACATZkV+3/qIEwFkdkV//t36iyABdX7N+om6iACZMiABVXdkXf/+iJsgF0V83fqBds3boBdkX/36qLIAF17d+ombqomTIAEyIBMgAbqLibqIMgMgMldF/t6AF2RVd+zN/s26qoMgEkZFft/6gFdFdERVduzd+okiAXVs3/qIuqIAEzIiAFVXZN3++oiDIBNldX3+R2Xd3+ibIFftm6ggAVZN/7qJuyIDEyCJuqiTIBE2Tem6iBITBHZf/u6LqBMgF3dkRXbN//qboDIDdXTf9kV3XfzNd3bN37qIMgFX7N+qiooCABMxIgBFd2Td/LqIgyAzZFd1dldt393+iKoTIBu6IgF2Tbu6iCAyBVdk3+y4mqARMgNpu6gTAkV2zf/szd+6qLIAMEV2Rez926iyATJFV0V+zd3+iKB2zduogBNk3+yKiJqAAyARETJkRXds3f26iAIBMkVXdVdt3f/t/oibEyJFdt/tuom7m6oBMkVXZN/t2bqIkiATIRMgEwdF/siTIGRf/JuqACE1VXZERV/N+oEwRVdF/s39+oqgEhCbIAF1bN+qiIkyIBE0RFd3ZEVXft39uoiAATA2VXVXZN3+7f7MV0V2Td/fqLqBdX+iBXdHbezf7om6iboAEyATJFZN36iIkyBkV+zbqoABIFV0BkVXTd/s5EVX3f7N/bqbqAEwEgIBbfibqgAhF2RVd3Tf/+5FV/7M37qqoAMhMgAwV2RXfu32RVdFfs3f+6gSAWV2Vk3f/omooCIJuomoABMgEkRXzduoiRMgNFfs26qCASBVcAJFV0Vd/s3+zdu6AXXd26iZMBISiaibkyIBdFV1Vf/+3f3+zf3f7N/JuqiDITALqJMgAyAldkVXZX/N/4uoEgdldl383fqKqCACAbqJqJAyADZEX9+6iJETIDATIJugAkVd3boAJVZFXf7N/omZMgNX7duomqAwEgIgEwIkVXRVdlX93938/s/+3+zf6buoizKouoi6oAAgABF2RXV33f7JqAAXRX7d/sm6qKggAgE4maiIMgEhZE3/6oiam6iokgATIEZEX/26ASRXV13+zf6IiTIGR+3bqIqoshIiABZHdVd2VXdVdd/9/szf/s/u36i6qIm6ibqJuqACICIBMkV0VV3+zfqAF9/+ibqJu6iaIgIFbd24iLIDIXZF/P6om4uoqJIBICASRV/fqAF0VXdP7N/v7WRf/s/t24qKiLoCIgBXV3VX/1V3V1Xf3f7M3/7f7s/tuoioqom6ibqoAgAiAAIVd2RV/9/f7N/7mom6ARMgEyIBdk39+oigISR2Rez+qJupICASAyAgEgAgEyADZFV2R2Xf/83+3f7N7dqLqoiyAgJFV1d1V//9/3dN/s3+zd/s387P7bqIqIqoqom6qIIBIgAAAVV3V33f3+zfuJuokgEyAFV2RX7N/bqLIAEkVk/s36iboAAgMgE6iJqKoBMgARE2ZEdlVf7N/t/+zezfqJqoIiIFVVd3ZVX/3f/f7PZEV0VXZVX/3+36qKiZqKqJuqioiyAAIgABVXdk3//s37qbqIMgIgVVfu3+iam6gyABdFdF7N+IiaADIDJFfsmbqoiTIAARMiRXV0V/7f7f7s3826iboAAgVXdVd3/d3/36iqggABMkV0VVd93////ouqiqi4uoqJqgAAIiABFXdVX/7N36i6qAIAMFdd/ouqipMgEgBGRXZN3fi6mgEyACBXZPy7qIm6AgEyAkV1dFV/3/3+7N/9momiAABVV2VV//3d+qqoqgAAADIFdVdVVV39//zeiIioqLqKiqqAACIgABJFV1X/39/tupqDIBRXzbqJqoISIBMkZkV2zf3oupsBMgAgEyVk+qiIqAIBIgNVdXRVdd/9/N7f35upIgBkVXd1Xf/f2bqogAAAACAyBXVXVVVVXd/8/siZqoiKiqiqiIIiIAACBFd1///Q==", + "mask_code": "////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////z////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Mz//Mz///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////zAMwAAMwAAAAMzM///zMz/////////////////////////////////////////////////////////////////////////////////////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAzM//////////////////////////////////////////////////////////////////////////////////////////////////////M8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAADM////////////////////////////////////////////////////////////////////////////////////////////////zMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzMADP////////////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM///////////////////////////////////////////////////////////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM///////////////////////////////////////////////////////////////////////////////8zMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz////////////////////////////////////////////////////////////////////////////MzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzP/////////////////////////////////////////////////////////////////////////MzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz///////////////////////////////////////////////////////////////////////zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz//////////////////////////////////////////////////////////////////////MzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMz///////////////////////////////MzMzMz///////////////////////////////8zMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzP/////////////////////////8zMAAAAAAAAAMz////////////////////////////MzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMw==", + "matched_with": [ + { + "distance": 0.3352968352968353, + "serial_id": 0 + } + ] + } +] diff --git a/compose.yml b/compose.yml index 4eda18f..6971c7c 100644 --- a/compose.yml +++ b/compose.yml @@ -37,6 +37,9 @@ services: dockerfile: Dockerfile ports: - 8080:8080 + depends_on: + - coordinator_db + - localstack participant_0: restart: always hostname: participant @@ -57,6 +60,9 @@ services: build: context: . dockerfile: Dockerfile + depends_on: + - participant_0_db + - localstack participant_1: restart: always hostname: participant @@ -74,6 +80,9 @@ services: - 'AWS_ACCESS_KEY_ID=test' - 'AWS_SECRET_ACCESS_KEY=test' - 'AWS_DEFAULT_REGION=us-east-1' + depends_on: + - participant_1_db + - localstack build: context: . dockerfile: Dockerfile diff --git a/src/bits.rs b/src/bits.rs index 559820f..4097c36 100644 --- a/src/bits.rs +++ b/src/bits.rs @@ -77,7 +77,7 @@ impl Index for Bits { fn index(&self, index: usize) -> &Self::Output { assert!(index < BITS); let (limb, bit) = (index / 64, index % 64); - let b = self.0[limb] & (1_u64 << bit) != 0; + let b = self.0[limb] & (1_u64 << (63 - bit)) != 0; if b { &true } else { @@ -273,33 +273,72 @@ impl ops::BitXorAssign<&Bits> for Bits { } #[cfg(test)] -mod tests { - use bytemuck::bytes_of; +pub mod tests { use rand::{thread_rng, Rng}; use super::*; + // u8 - 10101010 + pub const ODD_BITS_SET_PATTERN_SINGLE_BYTE_STR: &str = "10101010"; + pub const ODD_BITS_SET_PATTERN_SINGLE_BYTE: [u8; 1] = [170_u8; 1]; + pub const ODD_BITS_SET_PATTERN_SINGLE_BYTE_4_BYTES: [u8; 4] = [170_u8; 4]; + pub const ODD_BITS_SET_PATTERN_IRIS_CODE_BYTES: [u8; LIMBS * 8] = + [170_u8; LIMBS * 8]; + + // u8 - 11110000 + pub const FIRST_HALF_BITS_SET_PATTERN_BYTE_STR: &str = "11110000"; + pub const FIRST_HALF_BITS_SET_PATTERN_BYTE: [u8; 1] = [240_u8; 1]; + pub const FIRST_HALF_BITS_SET_PATTERN_4_BYTES: [u8; 4] = [240_u8; 4]; + pub const FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES: [u8; LIMBS * 8] = + [240_u8; LIMBS * 8]; + + // u64 - 1111111111111111111111111111111100000000000000000000000000000000 + pub const FIRST_HALF_BITS_SET_PATTERN_U64_STR: &str = + "1111111111111111111111111111111100000000000000000000000000000000"; + pub const FIRST_HALF_BITS_SET_PATTERN_U64_SINGLE: [u64; 1] = + [18446744069414584320_u64; 1]; + pub const FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE: [u64; LIMBS] = + [18446744069414584320_u64; LIMBS]; + #[test] fn limbs_exact() { assert_eq!(LIMBS * 64, BITS); } #[test] - fn test_index() { + fn test_index_random_pattern() { let mut rng = thread_rng(); for _ in 0..100 { let bits: Bits = rng.gen(); for location in 0..BITS { let actual = bits[location]; - let (byte, bit) = (location / 8, location % 8); - let expected = bytes_of(&bits)[byte] & (1_u8 << bit) != 0; + let bytes = u64_slice_to_u8_vec(&bits.0); + let expected = (bytes[byte] & (1_u8 << (7 - bit))) != 0; assert_eq!(actual, expected); } } } + #[test] + fn test_index_known_pattern() { + let bits = Bits(FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE); + + for location in 0..BITS { + let actual = bits[location]; + let (byte, bit) = (location / 8, location % 8); + let bytes = u64_slice_to_u8_vec(&bits.0); + let expected = bytes[byte] & (1_u8 << (7 - bit)) != 0; + + assert_eq!(actual, expected); + } + } + + fn u64_slice_to_u8_vec(s: &[u64]) -> Vec { + s.iter().flat_map(|x| x.to_be_bytes()).collect() + } + #[test] fn test_rotated_inverse() { let mut rng = thread_rng(); @@ -312,7 +351,7 @@ mod tests { } #[test] - fn bits_serialization() -> eyre::Result<()> { + fn bits_serialization_random_pattern() -> eyre::Result<()> { let mut bits = Bits::default(); // Random changes so that we don't convert all zeros @@ -331,4 +370,149 @@ mod tests { Ok(()) } + + #[test] + fn bits_deserialization_known_pattern() -> eyre::Result<()> { + let bytes_code = + u64_slice_to_u8_vec(&FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE); + let base64_code = format!("\"{}\"", BASE64_STANDARD.encode(bytes_code)); + + let deserialized: Bits = serde_json::from_str(&base64_code)?; + + assert_eq!( + binary_string_u64(&deserialized.0, false), + FIRST_HALF_BITS_SET_PATTERN_U64_STR.repeat(LIMBS) + ); + + Ok(()) + } + + #[test] + fn bits_serialization_known_pattern() -> eyre::Result<()> { + let bits: Bits = Bits(FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE); + + let serialized = serde_json::to_string(&bits)?; + + let bytes_code = + u64_slice_to_u8_vec(&FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE); + let base64_code = format!("\"{}\"", BASE64_STANDARD.encode(bytes_code)); + + assert_eq!(serialized, base64_code); + + Ok(()) + } + + #[test] + fn odd_bits_pattern() -> eyre::Result<()> { + assert_eq!( + binary_string_u8(&ODD_BITS_SET_PATTERN_SINGLE_BYTE, false), + ODD_BITS_SET_PATTERN_SINGLE_BYTE_STR + ); + assert_eq!( + binary_string_u8(&ODD_BITS_SET_PATTERN_SINGLE_BYTE_4_BYTES, false), + ODD_BITS_SET_PATTERN_SINGLE_BYTE_STR.repeat(4) + ); + assert_eq!( + binary_string_u8(&ODD_BITS_SET_PATTERN_IRIS_CODE_BYTES, false), + ODD_BITS_SET_PATTERN_SINGLE_BYTE_STR.repeat(LIMBS * 8) + ); + + Ok(()) + } + + #[test] + fn first_half_bits_pattern_u8() -> eyre::Result<()> { + assert_eq!( + binary_string_u8(&FIRST_HALF_BITS_SET_PATTERN_BYTE, false), + FIRST_HALF_BITS_SET_PATTERN_BYTE_STR + ); + assert_eq!( + binary_string_u8(&FIRST_HALF_BITS_SET_PATTERN_4_BYTES, false), + FIRST_HALF_BITS_SET_PATTERN_BYTE_STR.repeat(4) + ); + assert_eq!( + binary_string_u8( + &FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES, + false, + ), + FIRST_HALF_BITS_SET_PATTERN_BYTE_STR.repeat(LIMBS * 8) + ); + + Ok(()) + } + + #[test] + fn first_half_bits_pattern_u64() -> eyre::Result<()> { + assert_eq!( + binary_string_u64(&FIRST_HALF_BITS_SET_PATTERN_U64_SINGLE, true), + FIRST_HALF_BITS_SET_PATTERN_U64_STR + ); + assert_eq!( + binary_string_u64( + &FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE, + false, + ), + FIRST_HALF_BITS_SET_PATTERN_U64_STR.repeat(LIMBS) + ); + + Ok(()) + } + + #[test] + fn bits_from_u8() -> eyre::Result<()> { + let bits_u64 = Bits::from(FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES); + + assert_eq!( + binary_string_u8( + &FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES, + false, + ), + binary_string_u64(&bits_u64.0, false) + ); + + print_binary_representation_u8( + &FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES, + ); + print_binary_representation_u64(&bits_u64.0); + + Ok(()) + } + + #[test] + fn test_bytemuck_is_le_and_reverses_bit_pattern() { + print_binary_representation_u64( + &FIRST_HALF_BITS_SET_PATTERN_U64_SINGLE, + ); + let bytes = bytemuck::bytes_of(&FIRST_HALF_BITS_SET_PATTERN_U64_SINGLE); + print_binary_representation_u8(bytes); + + assert_eq!( + binary_string_u8(bytes, false), + "0000000000000000000000000000000011111111111111111111111111111111" + ) + } + + pub fn binary_string_u8(pattern: &[u8], separated: bool) -> String { + pattern + .iter() + .map(|byte| format!("{:08b}", byte)) + .collect::>() + .join(if separated { " " } else { "" }) + } + + pub fn print_binary_representation_u8(pattern: &[u8]) { + println!("{}", binary_string_u8(pattern, true)); + } + + pub fn print_binary_representation_u64(pattern: &[u64]) { + println!("{}", binary_string_u64(pattern, true)); + } + + pub fn binary_string_u64(pattern: &[u64], separated: bool) -> String { + pattern + .iter() + .map(|v| format!("{:064b}", v)) + .collect::>() + .join(if separated { " " } else { "" }) + } } diff --git a/src/encoded_bits.rs b/src/encoded_bits.rs index f1222ad..1da340d 100644 --- a/src/encoded_bits.rs +++ b/src/encoded_bits.rs @@ -15,7 +15,6 @@ use crate::bits::{Bits, BITS}; #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] - pub struct EncodedBits(pub [u16; BITS]); unsafe impl Zeroable for EncodedBits {} @@ -232,4 +231,103 @@ mod tests { assert_eq!(deserialized, encoded_bits); } + + use crate::bits::tests::*; + + #[test] + fn encoded_bits_deserialization_known_pattern() -> eyre::Result<()> { + let unpacked_bits_u16_first_half_set_pattern = + [[1_u16; 32], [0_u16; 32]].concat().repeat(BITS / 64); + + assert_eq!(unpacked_bits_u16_first_half_set_pattern.len(), BITS); + + let base64_code = format!( + "\"{}\"", + BASE64_STANDARD.encode(u16_slice_to_u8_vec( + &unpacked_bits_u16_first_half_set_pattern + )) + ); + + let deserialized = serde_json::from_str::(&base64_code) + .expect("Failed to deserialize EncodedBits"); + + assert_eq!( + binary_string_unpacked_u16(&deserialized, false), + FIRST_HALF_BITS_SET_PATTERN_U64_STR.repeat(BITS / 64) + ); + + Ok(()) + } + + #[test] + fn encoded_bits_serialization_known_pattern() -> eyre::Result<()> { + let bits: Bits = Bits(FIRST_HALF_BITS_SET_PATTERN_U64_IRIS_CODE); + assert_eq!(bits.0.len(), BITS / 64); // BITS = 12800 /64 => 200 + + let encoded_bits = EncodedBits::from(&bits); + assert_eq!(encoded_bits.0.len(), BITS); + + let serialized = serde_json::to_string(&encoded_bits)?; + + let bits_u16_pattern = + [[1_u16; 32], [0_u16; 32]].concat().repeat(BITS / 64); + + assert_eq!(bits_u16_pattern.len(), BITS); + + let base64_code = format!( + "\"{}\"", + BASE64_STANDARD.encode(u16_slice_to_u8_vec(&bits_u16_pattern)) + ); + + assert_eq!(serialized, base64_code); + + Ok(()) + } + + #[test] + fn unpack_from_bits_to_encoded_bits() -> eyre::Result<()> { + let bits_u64 = Bits::from(FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES); + let bits_u16_unpacked = EncodedBits::from(&bits_u64); + + print_binary_representation_u8( + &FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES, + ); + print_binary_representation_u64(&bits_u64.0); + print_binary_u16_unpacked(&bits_u16_unpacked); + assert_eq!( + binary_string_u8( + &FIRST_HALF_BITS_SET_PATTERN_IRIS_CODE_BYTES, + false, + ), + binary_string_unpacked_u16(&bits_u16_unpacked, false) + ); + print_binary_u16_unpacked(&bits_u16_unpacked); + + Ok(()) + } + + fn u16_slice_to_u8_vec(s: &[u16]) -> Vec { + s.iter().flat_map(|x| x.to_be_bytes()).collect() + } + + fn print_binary_u16_unpacked(bits: &EncodedBits) { + println!("{}", binary_string_unpacked_u16(bits, false)); + } + + fn binary_string_unpacked_u16( + bits: &EncodedBits, + separated: bool, + ) -> String { + bits.0 + .iter() + .map(|byte| { + if *byte == 1 { + String::from("1") + } else { + String::from("0") + } + }) + .collect::>() + .join(if separated { " " } else { "" }) + } }