/ console / algorithms / src / ecdsa / tests.rs
tests.rs
 1  // Copyright (c) 2025-2026 ACDC Network
 2  // This file is part of the alphavm library.
 3  //
 4  // Alpha Chain | Delta Chain Protocol
 5  // International Monetary Graphite.
 6  //
 7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
 8  // They built world-class ZK infrastructure. We installed the EASY button.
 9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
11  //
12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
14  // No rights reserved. No permission required. No warranty. No refunds.
15  //
16  // https://creativecommons.org/publicdomain/zero/1.0/
17  // SPDX-License-Identifier: CC0-1.0
18  
19  use super::*;
20  
21  const ITERATIONS: usize = 100;
22  
23  fn test_ecdsa<H: Hash<Output = Vec<bool>, Input = bool>>(hasher: &H, rng: &mut TestRng) {
24      for i in 1..ITERATIONS {
25          let (signing_key, message, signature) = test_helpers::sample_ecdsa_signature(i, hasher, rng);
26  
27          // Construct the verifying key.
28          let verifying_key = VerifyingKey::from(&signing_key);
29          let verifying_key_bytes = verifying_key.to_encoded_point(true).as_bytes().to_vec();
30          let recovered_verifying_key = ECDSASignature::verifying_key_from_bytes(&verifying_key_bytes).unwrap();
31          assert_eq!(verifying_key, recovered_verifying_key);
32  
33          // Verify the signature.
34          assert!(signature.verify(&verifying_key, hasher, &message.to_bits_le()).is_ok());
35          assert_eq!(signature.recover_public_key(hasher, &message.to_bits_le()).unwrap(), verifying_key);
36  
37          // Verify the signature using the digest.
38          let message_digest = hasher.hash(&message.to_bits_le()).unwrap();
39          assert!(signature.verify_with_digest(&verifying_key, &message_digest).is_ok());
40          assert_eq!(signature.recover_public_key_with_digest(&message_digest).unwrap(), verifying_key);
41      }
42  }
43  
44  #[test]
45  fn test_ecdsa_signature() {
46      let rng = &mut TestRng::default();
47  
48      test_ecdsa(&Keccak224::default(), rng);
49      test_ecdsa(&Keccak256::default(), rng);
50      test_ecdsa(&Keccak384::default(), rng);
51      test_ecdsa(&Keccak512::default(), rng);
52      test_ecdsa(&Sha3_224::default(), rng);
53      test_ecdsa(&Sha3_256::default(), rng);
54      test_ecdsa(&Sha3_384::default(), rng);
55      test_ecdsa(&Sha3_512::default(), rng);
56  }
57  
58  #[test]
59  fn test_ecdsa_signature_vector_1() {
60      let hasher = Keccak256::default();
61  
62      // Declare the test vector values.
63      let data_string = "0x2bcc5ce70000000100000000000000000000000000000000000000000000000000000000000f424000002712000000000000000000000000a0b86a33e6f8ec61cc62f1b0cb2ad6dfe3c10e8b000000000000000000000000742d35cc6e4c6e42e2a6e1b6d6e19d3bb14d3d1a000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002222222222222222222222222222222222222222000000000000000000000000000000000000000000000000000000000000c350bfab0940d5a2410c007e06c8b1bb24e34391ddc5298e18840df438e8e05b9ac800000000";
64      let signature_string = "0xab5373ec68978e102a9084d6d07aa1e328174d12337e0a028ec3b0c63abdb89e7a906d9de841006143de25cab83b380618972c4803bf978c5b02d4e863465b8a1b";
65      let expected_address = "0x1Be31A94361a391bBaFB2a4CCd704F57dc04d4bb";
66  
67      // Convert the test vector values to bytes.
68      let data_bytes = hex::decode(&data_string[2..]).unwrap();
69      let signature_bytes = hex::decode(&signature_string[2..]).unwrap();
70  
71      // Recover the public key from the signature.
72      let signature = ECDSASignature::from_bytes_le(&signature_bytes).unwrap();
73      let verifying_key = signature.recover_public_key(&hasher, &data_bytes.to_bits_le()).unwrap();
74  
75      // Check that the recovered public key matches the expected address.
76      let expected_address_bytes = ECDSASignature::ethereum_address_from_public_key(&verifying_key).unwrap();
77      assert_eq!(hex::decode(&expected_address[2..]).unwrap(), expected_address_bytes);
78  
79      // Check that the signature verifies against the recovered public key.
80      assert!(signature.verify(&verifying_key, &hasher, &data_bytes.to_bits_le()).is_ok());
81      assert!(signature.verify_ethereum(&expected_address_bytes, &hasher, &data_bytes.to_bits_le()).is_ok());
82  
83      // Check that the signature verifies using the digest.
84      let message_digest = hasher.hash(&data_bytes.to_bits_le()).unwrap();
85      assert!(signature.verify_with_digest(&verifying_key, &message_digest).is_ok());
86      assert!(signature.verify_ethereum_with_digest(&expected_address_bytes, &message_digest).is_ok());
87  
88      // Check that the signature does not verify against modified data.
89      let wrong_data = data_bytes[6..].to_vec();
90      let wrong_verifying_key = signature.recover_public_key(&hasher, &wrong_data.to_bits_le()).unwrap();
91      assert!(signature.verify(&wrong_verifying_key, &hasher, &data_bytes.to_bits_le()).is_err());
92  }