| 1 | // Copyright (c) blackshirt. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | // vtest build: has_modern_openssl? |
| 5 | module slhdsa |
| 6 | |
| 7 | import rand |
| 8 | import encoding.hex |
| 9 | |
| 10 | fn test_privatekey_from_bytes() ! { |
| 11 | // for sha2_128s |
| 12 | priv := |
| 13 | hex.decode('4329f96b412b5d5ca9c730c9d54e52595265f6fc3ea67c183aa7043d90e949b8fd320c8fc0fa6a23462483535f131b9ea265848e7bb5f4d3cfd99de2595382b3')! |
| 14 | mut pv := PrivateKey.from_bytes(priv, .sha2_128s)! |
| 15 | |
| 16 | sig := pv.sign('test'.bytes())! |
| 17 | |
| 18 | mut pb := pv.public_key()! |
| 19 | status := pb.verify(sig, 'test'.bytes())! |
| 20 | assert status == true |
| 21 | |
| 22 | pv.free() |
| 23 | pb.free() |
| 24 | } |
| 25 | |
| 26 | fn test_pvkey_from_seed() ! { |
| 27 | kind := Kind.sha2_128s |
| 28 | seed := rand.bytes(3 * kind.nsize())! |
| 29 | |
| 30 | mut pv := PrivateKey.from_seed(seed, kind)! |
| 31 | |
| 32 | msg := 'Hello'.bytes() |
| 33 | sig := pv.sign(msg)! |
| 34 | |
| 35 | mut pb := pv.public_key()! |
| 36 | |
| 37 | verified := pb.verify(sig, msg)! |
| 38 | assert verified |
| 39 | |
| 40 | pv.free() |
| 41 | pb.free() |
| 42 | } |
| 43 | |
| 44 | fn test_privkey_signing() ! { |
| 45 | mut pv := PrivateKey.new(kind: .shake_256f)! |
| 46 | assert pv.bytes()!.len == 128 |
| 47 | assert pv.public_bytes()!.len == 64 |
| 48 | |
| 49 | // type name |
| 50 | chr := key_type_name(pv.key) |
| 51 | assert unsafe { chr.vstring() } == 'SLH-DSA-SHAKE-256f' |
| 52 | |
| 53 | msg := 'Hello'.bytes() |
| 54 | sig := slhdsa_do_sign(pv.key, msg)! |
| 55 | assert sig.len == 49856 |
| 56 | |
| 57 | verified := slhdsa_do_verify(pv.key, sig, msg)! |
| 58 | assert verified |
| 59 | |
| 60 | mut pb := pv.public_key()! |
| 61 | sig2 := pv.sign(msg)! |
| 62 | |
| 63 | status := pb.verify(sig, msg)! |
| 64 | status2 := pb.verify(sig2, msg)! |
| 65 | |
| 66 | assert status |
| 67 | assert status2 |
| 68 | |
| 69 | pv.free() |
| 70 | pb.free() |
| 71 | } |
| 72 | |
| 73 | fn test_basic_properties() ! { |
| 74 | mut pv := PrivateKey.new()! |
| 75 | desc := key_description(pv.key) |
| 76 | unsafe { desc.vstring() } == 'OpenSSL SLH-DSA-SHA2-128f implementation' |
| 77 | |
| 78 | n := C.EVP_PKEY_is_a(pv.key, ln_slhdsa_sha2_128s) |
| 79 | assert n == 1 // true |
| 80 | assert C.EVP_PKEY_size(pv.key) == 7856 |
| 81 | assert C.EVP_PKEY_get_bits(pv.key) == 256 |
| 82 | assert C.EVP_PKEY_get_security_bits(pv.key) == 128 |
| 83 | |
| 84 | mut pv2 := PrivateKey.new(kind: .sha2_128f)! |
| 85 | n2 := C.EVP_PKEY_is_a(pv2.key, ln_slhdsa_sha2_128f) |
| 86 | assert n2 == 1 // true |
| 87 | assert C.EVP_PKEY_size(pv2.key) == 17088 |
| 88 | assert C.EVP_PKEY_get_bits(pv2.key) == 256 |
| 89 | assert C.EVP_PKEY_get_security_bits(pv2.key) == 128 |
| 90 | |
| 91 | mut pv3 := PrivateKey.new(kind: .sha2_192s)! |
| 92 | n3 := C.EVP_PKEY_is_a(pv3.key, ln_slhdsa_sha2_192s) |
| 93 | assert n3 == 1 // true |
| 94 | assert C.EVP_PKEY_size(pv3.key) == 16224 |
| 95 | assert C.EVP_PKEY_get_bits(pv3.key) == 384 |
| 96 | assert C.EVP_PKEY_get_security_bits(pv3.key) == 192 |
| 97 | |
| 98 | mut pv4 := PrivateKey.new(kind: .shake_256f)! |
| 99 | n4 := C.EVP_PKEY_is_a(pv4.key, ln_slhdsa_shake_256f) |
| 100 | assert n4 == 1 // true |
| 101 | assert C.EVP_PKEY_size(pv4.key) == 49856 |
| 102 | assert C.EVP_PKEY_get_bits(pv4.key) == 512 |
| 103 | assert C.EVP_PKEY_get_security_bits(pv4.key) == 256 |
| 104 | |
| 105 | pv.free() |
| 106 | pv2.free() |
| 107 | pv3.free() |
| 108 | pv4.free() |
| 109 | } |
| 110 | |
| 111 | struct Slh128sSeed { |
| 112 | mut: |
| 113 | seed string |
| 114 | pubk string |
| 115 | priv string |
| 116 | } |
| 117 | |
| 118 | // test SLH-DSA-SHA2_128s based on samples data |
| 119 | fn test_privatekey_slhdsa_128s_from_seed_with_sample_data() ! { |
| 120 | for obj in sample_slhdsa_128s_seed { |
| 121 | seed := hex.decode(obj.seed)! |
| 122 | k_opt := KeyOpts{ |
| 123 | kind: .sha2_128s |
| 124 | flag: 1 |
| 125 | seed: seed |
| 126 | } |
| 127 | mut pv := PrivateKey.new(k_opt)! |
| 128 | assert pv.bytes()! == hex.decode(obj.priv)! |
| 129 | assert pv.public_bytes()! == hex.decode(obj.pubk)! |
| 130 | pv.free() |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | // This sample data was copied and adapted from boringssl test data in slh_keygen.txt |
| 135 | // at https://boringssl.googlesource.com/boringssl.git/+/chromium-stable/crypto/slhdsa/slhdsa_keygen.txt |
| 136 | // Its likely only support for SLH-DSA-SHA2_128s |
| 137 | const sample_slhdsa_128s_seed = [ |
| 138 | Slh128sSeed{ |
| 139 | seed: '2f896d61d9cd9038ca303394fadaa22a24ac5ec1d86a989ca2196c3c8632419c1a05a42fe300e87b16aee116cb2e2363' |
| 140 | pubk: '1a05a42fe300e87b16aee116cb2e236358e2c3e62632c9de03d08a535a0eb7e7' |
| 141 | priv: '2f896d61d9cd9038ca303394fadaa22a24ac5ec1d86a989ca2196c3c8632419c1a05a42fe300e87b16aee116cb2e236358e2c3e62632c9de03d08a535a0eb7e7' |
| 142 | }, |
| 143 | Slh128sSeed{ |
| 144 | seed: '87dd614ea188940d93c7df9943caa283cbdf2ccc4940e7007b7b6c799e95e160bbaca7b93fec1a097e115f10d18e6611' |
| 145 | pubk: 'bbaca7b93fec1a097e115f10d18e66112aa087f0eeed95be3ab301ebc812406f' |
| 146 | priv: '87dd614ea188940d93c7df9943caa283cbdf2ccc4940e7007b7b6c799e95e160bbaca7b93fec1a097e115f10d18e66112aa087f0eeed95be3ab301ebc812406f' |
| 147 | }, |
| 148 | Slh128sSeed{ |
| 149 | seed: '0436b480d04c4c47f5ecd1e4b94f103988c5f804913fac77a96572cdc26f6a92f18d59d50b6b13f71821526f3aa800a8' |
| 150 | pubk: 'f18d59d50b6b13f71821526f3aa800a8cde5ccb604485df0c6f14cd64b60979c' |
| 151 | priv: '0436b480d04c4c47f5ecd1e4b94f103988c5f804913fac77a96572cdc26f6a92f18d59d50b6b13f71821526f3aa800a8cde5ccb604485df0c6f14cd64b60979c' |
| 152 | }, |
| 153 | Slh128sSeed{ |
| 154 | seed: 'b9341d201d49b337c84e6ac2c26361e1f5dcab582f404fe89739df4ec64eccdd04519d0d7c1ad543cd1b479602e41784' |
| 155 | pubk: '04519d0d7c1ad543cd1b479602e417848aeb88695d05f531a8415a4365b62983' |
| 156 | priv: 'b9341d201d49b337c84e6ac2c26361e1f5dcab582f404fe89739df4ec64eccdd04519d0d7c1ad543cd1b479602e417848aeb88695d05f531a8415a4365b62983' |
| 157 | }, |
| 158 | Slh128sSeed{ |
| 159 | seed: 'cbcaec354573e8cee1373b7aced67cdc683ed4491e17ef1dff9a9163fe7bcf74d91e0df4756c799ada2a0cf1b1aada1d' |
| 160 | pubk: 'd91e0df4756c799ada2a0cf1b1aada1d1fddc3692e8909f2185e11654dc84def' |
| 161 | priv: 'cbcaec354573e8cee1373b7aced67cdc683ed4491e17ef1dff9a9163fe7bcf74d91e0df4756c799ada2a0cf1b1aada1d1fddc3692e8909f2185e11654dc84def' |
| 162 | }, |
| 163 | Slh128sSeed{ |
| 164 | seed: '1d92b6cc53e5bb08841b2669f1fb481c62db8f494e1bac12a6c6163142842a33771c182ffb096207da6476874ebdaf15' |
| 165 | pubk: '771c182ffb096207da6476874ebdaf158c0143adbd0f66057a5180c96467d31d' |
| 166 | priv: '1d92b6cc53e5bb08841b2669f1fb481c62db8f494e1bac12a6c6163142842a33771c182ffb096207da6476874ebdaf158c0143adbd0f66057a5180c96467d31d' |
| 167 | }, |
| 168 | Slh128sSeed{ |
| 169 | seed: '94b11b26e2ec430f413f353fae96c144915e7ec84e9c786c895593b859bdb0edd54cc085cb4f4265f8288a9d67ae5806' |
| 170 | pubk: 'd54cc085cb4f4265f8288a9d67ae5806ac638ad976a1fc8e2c7c5b9db2ea0573' |
| 171 | priv: '94b11b26e2ec430f413f353fae96c144915e7ec84e9c786c895593b859bdb0edd54cc085cb4f4265f8288a9d67ae5806ac638ad976a1fc8e2c7c5b9db2ea0573' |
| 172 | }, |
| 173 | Slh128sSeed{ |
| 174 | seed: '9078f099c6420c6bb1303977029b1e1bac048a4375f3c48862f74a6ccedb5be4755e624791fbfd27cd195ce3aa32c62c' |
| 175 | pubk: '755e624791fbfd27cd195ce3aa32c62cd9030c131ca25c8c442c4ac0b27ae548' |
| 176 | priv: '9078f099c6420c6bb1303977029b1e1bac048a4375f3c48862f74a6ccedb5be4755e624791fbfd27cd195ce3aa32c62cd9030c131ca25c8c442c4ac0b27ae548' |
| 177 | }, |
| 178 | Slh128sSeed{ |
| 179 | seed: 'e0c67d9fb2434e27165c861c0f1040ed58c13b7f5e9517d000770bd3e88fbdb48cdf5f1cc1aa770a8bafcf1b8c5c843b' |
| 180 | pubk: '8cdf5f1cc1aa770a8bafcf1b8c5c843ba659b85d99ca18f555b8452f411b519c' |
| 181 | priv: 'e0c67d9fb2434e27165c861c0f1040ed58c13b7f5e9517d000770bd3e88fbdb48cdf5f1cc1aa770a8bafcf1b8c5c843ba659b85d99ca18f555b8452f411b519c' |
| 182 | }, |
| 183 | Slh128sSeed{ |
| 184 | seed: 'ccae2481cecc4a55aa2afe4874b0ce501984d48423fc2452f24f49b2a68ef9b8d66807ecbfd2dc999d274d0d6414afc3' |
| 185 | pubk: 'd66807ecbfd2dc999d274d0d6414afc3dfba899a4f7799cf74e98dc1c82a26ab' |
| 186 | priv: 'ccae2481cecc4a55aa2afe4874b0ce501984d48423fc2452f24f49b2a68ef9b8d66807ecbfd2dc999d274d0d6414afc3dfba899a4f7799cf74e98dc1c82a26ab' |
| 187 | }, |
| 188 | ] |
| 189 | |