/* * Copyright (c) 2022, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1 TEST_CASE(TEST_1) { u8 private_bytes[32] = { 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60 }; u8 public_bytes[32] = { 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a }; u8 message_bytes[0] = {}; u8 signature_bytes[64] = { 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a, 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74, 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55, 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac, 0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b }; ReadonlyBytes private_key { private_bytes, 32 }; ReadonlyBytes public_key { public_bytes, 32 }; ReadonlyBytes message { message_bytes, 0 }; ReadonlyBytes expected_signature { signature_bytes, 64 }; Crypto::Curves::Ed25519 curve; auto generated_signature = TRY_OR_FAIL(curve.sign(private_key, message)); EXPECT_EQ(generated_signature, expected_signature); EXPECT(TRY_OR_FAIL(curve.verify(public_key, expected_signature, message))); } // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1 TEST_CASE(TEST_2) { u8 private_bytes[32] = { 0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda, 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f, 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24, 0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb }; u8 public_bytes[32] = { 0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a, 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc, 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c, 0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c }; u8 message_bytes[1] = { 0x72 }; u8 signature_bytes[64] = { 0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8, 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40, 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f, 0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda, 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e, 0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, 0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00 }; ReadonlyBytes private_key { private_bytes, 32 }; ReadonlyBytes public_key { public_bytes, 32 }; ReadonlyBytes message { message_bytes, 1 }; ReadonlyBytes expected_signature { signature_bytes, 64 }; Crypto::Curves::Ed25519 curve; auto generated_signature = TRY_OR_FAIL(curve.sign(private_key, message)); EXPECT_EQ(generated_signature, expected_signature); EXPECT(TRY_OR_FAIL(curve.verify(public_key, expected_signature, message))); } // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1 TEST_CASE(TEST_3) { u8 private_bytes[32] = { 0xc5, 0xaa, 0x8d, 0xf4, 0x3f, 0x9f, 0x83, 0x7b, 0xed, 0xb7, 0x44, 0x2f, 0x31, 0xdc, 0xb7, 0xb1, 0x66, 0xd3, 0x85, 0x35, 0x07, 0x6f, 0x09, 0x4b, 0x85, 0xce, 0x3a, 0x2e, 0x0b, 0x44, 0x58, 0xf7 }; u8 public_bytes[32] = { 0xfc, 0x51, 0xcd, 0x8e, 0x62, 0x18, 0xa1, 0xa3, 0x8d, 0xa4, 0x7e, 0xd0, 0x02, 0x30, 0xf0, 0x58, 0x08, 0x16, 0xed, 0x13, 0xba, 0x33, 0x03, 0xac, 0x5d, 0xeb, 0x91, 0x15, 0x48, 0x90, 0x80, 0x25 }; u8 message_bytes[2] = { 0xaf, 0x82 }; u8 signature_bytes[64] = { 0x62, 0x91, 0xd6, 0x57, 0xde, 0xec, 0x24, 0x02, 0x48, 0x27, 0xe6, 0x9c, 0x3a, 0xbe, 0x01, 0xa3, 0x0c, 0xe5, 0x48, 0xa2, 0x84, 0x74, 0x3a, 0x44, 0x5e, 0x36, 0x80, 0xd7, 0xdb, 0x5a, 0xc3, 0xac, 0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90, 0xae, 0x67, 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59, 0x4a, 0x7c, 0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d, 0xc0, 0x27, 0xbe, 0xce, 0xea, 0x1e, 0xc4, 0x0a }; ReadonlyBytes private_key { private_bytes, 32 }; ReadonlyBytes public_key { public_bytes, 32 }; ReadonlyBytes message { message_bytes, 2 }; ReadonlyBytes expected_signature { signature_bytes, 64 }; Crypto::Curves::Ed25519 curve; auto generated_signature = TRY_OR_FAIL(curve.sign(private_key, message)); EXPECT_EQ(generated_signature, expected_signature); EXPECT(TRY_OR_FAIL(curve.verify(public_key, expected_signature, message))); } // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1 TEST_CASE(TEST_1024) { u8 private_bytes[32] = { 0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95, 0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c, 0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74, 0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5 }; u8 public_bytes[32] = { 0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34, 0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86, 0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5, 0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e }; u8 message_bytes[1023] = { 0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43, 0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08, 0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91, 0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98, 0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12, 0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1, 0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f, 0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8, 0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96, 0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57, 0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37, 0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d, 0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0, 0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c, 0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b, 0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc, 0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3, 0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a, 0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e, 0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe, 0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82, 0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b, 0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6, 0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e, 0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8, 0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9, 0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28, 0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef, 0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68, 0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10, 0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1, 0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7, 0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04, 0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4, 0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53, 0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1, 0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44, 0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9, 0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5, 0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2, 0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59, 0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d, 0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce, 0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24, 0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6, 0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd, 0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf, 0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70, 0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59, 0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53, 0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78, 0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc, 0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9, 0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b, 0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2, 0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07, 0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75, 0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a, 0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d, 0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba, 0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31, 0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b, 0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22, 0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a, 0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78, 0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b, 0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88, 0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e, 0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9, 0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8, 0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4, 0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7, 0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55, 0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1, 0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01, 0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c, 0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb, 0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d, 0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c, 0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8, 0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb, 0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8, 0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14, 0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf, 0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9, 0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27, 0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b, 0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08, 0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a, 0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7, 0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67, 0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49, 0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f, 0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57, 0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a, 0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4, 0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5, 0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1, 0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d, 0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3, 0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e, 0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09, 0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79, 0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e, 0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4, 0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2, 0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66, 0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f, 0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98, 0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41, 0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c, 0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5, 0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3, 0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61, 0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9, 0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1, 0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45, 0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34, 0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd, 0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d, 0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85, 0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e, 0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47, 0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c, 0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef, 0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca, 0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08, 0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0 }; u8 signature_bytes[64] = { 0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2, 0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a, 0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb, 0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50, 0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45, 0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b, 0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6, 0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03 }; ReadonlyBytes private_key { private_bytes, 32 }; ReadonlyBytes public_key { public_bytes, 32 }; ReadonlyBytes message { message_bytes, 1023 }; ReadonlyBytes expected_signature { signature_bytes, 64 }; Crypto::Curves::Ed25519 curve; auto generated_signature = TRY_OR_FAIL(curve.sign(private_key, message)); EXPECT_EQ(generated_signature, expected_signature); EXPECT(TRY_OR_FAIL(curve.verify(public_key, expected_signature, message))); } // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1 TEST_CASE(TEST_SHA_ABC) { u8 private_bytes[32] = { 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e, 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42 }; u8 public_bytes[32] = { 0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b, 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34, 0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64, 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf }; u8 message_bytes[64] = { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }; u8 signature_bytes[64] = { 0xdc, 0x2a, 0x44, 0x59, 0xe7, 0x36, 0x96, 0x33, 0xa5, 0x2b, 0x1b, 0xf2, 0x77, 0x83, 0x9a, 0x00, 0x20, 0x10, 0x09, 0xa3, 0xef, 0xbf, 0x3e, 0xcb, 0x69, 0xbe, 0xa2, 0x18, 0x6c, 0x26, 0xb5, 0x89, 0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec, 0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30, 0x3d, 0xca, 0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a, 0xd9, 0xbe, 0xf1, 0x17, 0x73, 0x31, 0xa7, 0x04 }; ReadonlyBytes private_key { private_bytes, 32 }; ReadonlyBytes public_key { public_bytes, 32 }; ReadonlyBytes message { message_bytes, 64 }; ReadonlyBytes expected_signature { signature_bytes, 64 }; Crypto::Curves::Ed25519 curve; auto generated_signature = TRY_OR_FAIL(curve.sign(private_key, message)); EXPECT_EQ(generated_signature, expected_signature); EXPECT(TRY_OR_FAIL(curve.verify(public_key, expected_signature, message))); } // Test case for small-order point rejection TEST_CASE(small_order_point_rejection) { Crypto::Curves::Ed25519 curve; // Test message u8 message_bytes[5] = { 0x68, 0x65, 0x6c, 0x6c, 0x6f }; // "hello" ReadonlyBytes message { message_bytes, 5 }; // Identity point (order 1) - should be rejected u8 identity_point[32] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Point of order 2 - should be rejected u8 order_2_point[32] = { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }; // Point of order 4 - should be rejected u8 order_4_point[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }; // Point of order 8 - should be rejected u8 order_8_point[32] = { 0xee, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; // WPT test small-order point (pubKeys[0]) - should be rejected u8 wpt_small_order_point[32] = { 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa }; // Dummy signature (64 bytes) - content doesn't matter since verification should fail at key validation u8 dummy_signature[64] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ReadonlyBytes signature { dummy_signature, 64 }; // All of these should return false (verification failure due to small-order point) auto result1 = TRY_OR_FAIL(curve.verify(ReadonlyBytes { identity_point, 32 }, signature, message)); EXPECT(!result1); auto result2 = TRY_OR_FAIL(curve.verify(ReadonlyBytes { order_2_point, 32 }, signature, message)); EXPECT(!result2); auto result3 = TRY_OR_FAIL(curve.verify(ReadonlyBytes { order_4_point, 32 }, signature, message)); EXPECT(!result3); auto result4 = TRY_OR_FAIL(curve.verify(ReadonlyBytes { order_8_point, 32 }, signature, message)); EXPECT(!result4); auto result5 = TRY_OR_FAIL(curve.verify(ReadonlyBytes { wpt_small_order_point, 32 }, signature, message)); EXPECT(!result5); } // Test case for small-order R point in signature rejection TEST_CASE(small_order_signature_r_point_rejection) { Crypto::Curves::Ed25519 curve; // Test message u8 message_bytes[5] = { 0x68, 0x65, 0x6c, 0x6c, 0x6f }; // "hello" ReadonlyBytes message { message_bytes, 5 }; // Valid public key (from TEST_1) u8 valid_public_key[32] = { 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a }; // Signature with small-order R point (first 32 bytes) - should be rejected u8 signature_with_small_order_r[64] = { // R point: identity point (order 1) 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // S value (dummy) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ReadonlyBytes public_key { valid_public_key, 32 }; ReadonlyBytes signature { signature_with_small_order_r, 64 }; // This should return false (verification failure due to small-order R point in signature) auto result = TRY_OR_FAIL(curve.verify(public_key, signature, message)); EXPECT(!result); }