Finish EC NIST curves implementation.
Add EC NIST curves tests and test vectors.
This commit is contained in:
parent
f67a7a2a3e
commit
1aaf4797c9
|
@ -19,4 +19,5 @@ task test, "Runs the test suite":
|
||||||
exec "nim c -r tests/testmultihash"
|
exec "nim c -r tests/testmultihash"
|
||||||
exec "nim c -r tests/testmultibase"
|
exec "nim c -r tests/testmultibase"
|
||||||
exec "nim c -r tests/testcid"
|
exec "nim c -r tests/testcid"
|
||||||
|
exec "nim c -r tests/testecnist"
|
||||||
exec "nim c -r tests/testdaemon"
|
exec "nim c -r tests/testdaemon"
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
## Nim-Libp2p
|
||||||
|
## Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
## Licensed under either of
|
||||||
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
## at your option.
|
||||||
|
## This file may not be copied, modified, or distributed except according to
|
||||||
|
## those terms.
|
||||||
|
|
||||||
|
## This module implements interface with BearSSL library sources.
|
||||||
import strutils
|
import strutils
|
||||||
from os import DirSep
|
from os import DirSep
|
||||||
|
|
||||||
when defined(vcc):
|
|
||||||
{.passC: "/Zi /FS".}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
bearPath = currentSourcePath.rsplit(DirSep, 1)[0] & DirSep &
|
bearPath = currentSourcePath.rsplit(DirSep, 1)[0] & DirSep &
|
||||||
"BearSSL" & DirSep
|
"BearSSL" & DirSep
|
||||||
|
@ -625,6 +632,16 @@ proc brEcdsaVerifyRaw*(impl: ptr BrEcImplementation, hash: pointer,
|
||||||
siglen: int): uint32 {.
|
siglen: int): uint32 {.
|
||||||
cdecl, importc: "br_ecdsa_i31_vrfy_raw", header: "bearssl_ec.h".}
|
cdecl, importc: "br_ecdsa_i31_vrfy_raw", header: "bearssl_ec.h".}
|
||||||
|
|
||||||
|
proc brEcdsaSignAsn1*(impl: ptr BrEcImplementation, hf: ptr BrHashClass,
|
||||||
|
value: pointer, sk: ptr BrEcPrivateKey,
|
||||||
|
sig: pointer): int {.
|
||||||
|
cdecl, importc: "br_ecdsa_i31_sign_asn1", header: "bearssl_ec.h".}
|
||||||
|
|
||||||
|
proc brEcdsaVerifyAsn1*(impl: ptr BrEcImplementation, hash: pointer,
|
||||||
|
hashlen: int, pk: ptr BrEcPublicKey, sig: pointer,
|
||||||
|
siglen: int): uint32 {.
|
||||||
|
cdecl, importc: "br_ecdsa_i31_vrfy_asn1", header: "bearssl_ec.h".}
|
||||||
|
|
||||||
proc brAsn1UintPrepare*(xdata: pointer, xlen: int): BrAsn1Uint {.
|
proc brAsn1UintPrepare*(xdata: pointer, xlen: int): BrAsn1Uint {.
|
||||||
cdecl, importc: "br_asn1_uint_prepare", header: "inner.h".}
|
cdecl, importc: "br_asn1_uint_prepare", header: "inner.h".}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,13 @@
|
||||||
## at your option.
|
## at your option.
|
||||||
## This file may not be copied, modified, or distributed except according to
|
## This file may not be copied, modified, or distributed except according to
|
||||||
## those terms.
|
## those terms.
|
||||||
|
|
||||||
|
## This module implements ECDSA and ECDHE for NIST elliptic curves
|
||||||
|
## secp256r1, secp384r1 and secp521r1.
|
||||||
import common
|
import common
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import minasn1
|
import minasn1
|
||||||
|
export minasn1.Asn1Status
|
||||||
|
|
||||||
const
|
const
|
||||||
PubKey256Length* = 65
|
PubKey256Length* = 65
|
||||||
|
@ -36,7 +40,6 @@ type
|
||||||
|
|
||||||
EcSignature* = ref object
|
EcSignature* = ref object
|
||||||
buffer*: seq[byte]
|
buffer*: seq[byte]
|
||||||
curve*: cint
|
|
||||||
|
|
||||||
EcCurveKind* = enum
|
EcCurveKind* = enum
|
||||||
Secp256r1 = BR_EC_SECP256R1,
|
Secp256r1 = BR_EC_SECP256R1,
|
||||||
|
@ -121,15 +124,6 @@ proc getOffset(seckey: EcPrivateKey): int {.inline.} =
|
||||||
else:
|
else:
|
||||||
result = cast[int](o)
|
result = cast[int](o)
|
||||||
|
|
||||||
template getSignatureLength*(curve: EcCurveKind): int =
|
|
||||||
case curve
|
|
||||||
of Secp256r1:
|
|
||||||
Sig256Length
|
|
||||||
of Secp384r1:
|
|
||||||
Sig384Length
|
|
||||||
of Secp521r1:
|
|
||||||
Sig521Length
|
|
||||||
|
|
||||||
template getPublicKeyLength*(curve: EcCurveKind): int =
|
template getPublicKeyLength*(curve: EcCurveKind): int =
|
||||||
case curve
|
case curve
|
||||||
of Secp256r1:
|
of Secp256r1:
|
||||||
|
@ -139,15 +133,6 @@ template getPublicKeyLength*(curve: EcCurveKind): int =
|
||||||
of Secp521r1:
|
of Secp521r1:
|
||||||
PubKey521Length
|
PubKey521Length
|
||||||
|
|
||||||
template getPrivateKeyLength*(curve: EcCurveKind): int =
|
|
||||||
case curve
|
|
||||||
of Secp256r1:
|
|
||||||
SecKey256Length
|
|
||||||
of Secp384r1:
|
|
||||||
SecKey384Length
|
|
||||||
of Secp521r1:
|
|
||||||
SecKey521Length
|
|
||||||
|
|
||||||
proc copy*[T: EcPKI](dst: var T, src: T): bool =
|
proc copy*[T: EcPKI](dst: var T, src: T): bool =
|
||||||
## Copy EC private key, public key or scalar ``src`` to ``dst``.
|
## Copy EC private key, public key or scalar ``src`` to ``dst``.
|
||||||
##
|
##
|
||||||
|
@ -288,12 +273,6 @@ proc `$`*(pubkey: EcPublicKey): string =
|
||||||
|
|
||||||
proc `$`*(sig: EcSignature): string =
|
proc `$`*(sig: EcSignature): string =
|
||||||
## Return hexadecimal string representation of EC signature.
|
## Return hexadecimal string representation of EC signature.
|
||||||
if sig.curve == 0 or len(sig.buffer) == 0:
|
|
||||||
result = "Empty signature"
|
|
||||||
else:
|
|
||||||
if sig.curve notin EcSupportedCurvesCint:
|
|
||||||
result = "Unknown signature"
|
|
||||||
else:
|
|
||||||
result = toHex(sig.buffer)
|
result = toHex(sig.buffer)
|
||||||
|
|
||||||
proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
|
proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
|
||||||
|
@ -332,8 +311,8 @@ proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
|
||||||
b.write(p)
|
b.write(p)
|
||||||
b.finish()
|
b.finish()
|
||||||
result = len(b)
|
result = len(b)
|
||||||
if len(data) >= len(b):
|
if len(data) >= result:
|
||||||
copyMem(addr data[0], addr b.buffer[0], len(b))
|
copyMem(addr data[0], addr b.buffer[0], result)
|
||||||
|
|
||||||
proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
|
proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
|
||||||
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and store it
|
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and store it
|
||||||
|
@ -362,8 +341,18 @@ proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
|
||||||
b.write(p)
|
b.write(p)
|
||||||
b.finish()
|
b.finish()
|
||||||
result = len(b)
|
result = len(b)
|
||||||
if len(data) >= len(b):
|
if len(data) >= result:
|
||||||
copyMem(addr data[0], addr b.buffer[0], len(b))
|
copyMem(addr data[0], addr b.buffer[0], result)
|
||||||
|
|
||||||
|
proc toBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
||||||
|
## Serialize EC signature ``sig`` to ASN.1 DER binary form and store it
|
||||||
|
## to ``data``.
|
||||||
|
##
|
||||||
|
## Procedure returns number of bytes (octets) needed to store EC signature,
|
||||||
|
## or `0` if signature is not in supported curve.
|
||||||
|
result = len(sig.buffer)
|
||||||
|
if len(data) >= result:
|
||||||
|
copyMem(addr data[0], unsafeAddr sig.buffer[0], result)
|
||||||
|
|
||||||
proc getBytes*(seckey: EcPrivateKey): seq[byte] =
|
proc getBytes*(seckey: EcPrivateKey): seq[byte] =
|
||||||
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and return it.
|
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and return it.
|
||||||
|
@ -385,6 +374,13 @@ proc getBytes*(pubkey: EcPublicKey): seq[byte] =
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect public key")
|
raise newException(EcKeyIncorrectError, "Incorrect public key")
|
||||||
|
|
||||||
|
proc getBytes*(sig: EcSignature): seq[byte] =
|
||||||
|
## Serialize EC signature ``sig`` to ASN.1 DER binary form and return it.
|
||||||
|
result = newSeq[byte]()
|
||||||
|
let length = sig.toBytes(result)
|
||||||
|
result.setLen(length)
|
||||||
|
discard sig.toBytes(result)
|
||||||
|
|
||||||
proc `==`*(pubkey1, pubkey2: EcPublicKey): bool =
|
proc `==`*(pubkey1, pubkey2: EcPublicKey): bool =
|
||||||
## Returns ``true`` if both keys ``pubkey1`` and ``pubkey2`` are equal.
|
## Returns ``true`` if both keys ``pubkey1`` and ``pubkey2`` are equal.
|
||||||
if pubkey1.key.curve != pubkey2.key.curve:
|
if pubkey1.key.curve != pubkey2.key.curve:
|
||||||
|
@ -413,8 +409,6 @@ proc `==`*(seckey1, seckey2: EcPrivateKey): bool =
|
||||||
|
|
||||||
proc `==`*(sig1, sig2: EcSignature): bool =
|
proc `==`*(sig1, sig2: EcSignature): bool =
|
||||||
## Return ``true`` if both signatures ``sig1`` and ``sig2`` are equal.
|
## Return ``true`` if both signatures ``sig1`` and ``sig2`` are equal.
|
||||||
if sig1.curve != sig2.curve:
|
|
||||||
return false
|
|
||||||
result = (sig1.buffer == sig2.buffer)
|
result = (sig1.buffer == sig2.buffer)
|
||||||
|
|
||||||
proc init*(key: var EcPrivateKey, data: openarray[byte]): Asn1Status =
|
proc init*(key: var EcPrivateKey, data: openarray[byte]): Asn1Status =
|
||||||
|
@ -539,35 +533,21 @@ proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Asn1Status =
|
||||||
else:
|
else:
|
||||||
result = Asn1Status.Incorrect
|
result = Asn1Status.Incorrect
|
||||||
|
|
||||||
proc init*(sig: var EcSignature, data: openarray[byte]): bool =
|
proc init*(sig: var EcSignature, data: openarray[byte]): Asn1Status =
|
||||||
## Initialize EC signature ``sig`` from raw binary representation ``data``.
|
## Initialize EC signature ``sig`` from raw binary representation ``data``.
|
||||||
##
|
##
|
||||||
## Length of ``data`` array must be ``Sig256Length``, ``Sig384Length``
|
## Procedure returns ``Asn1Status``.
|
||||||
## or ``Sig521Length``.
|
result = Asn1Status.Incorrect
|
||||||
##
|
|
||||||
## Procedure returns ``true`` on success, ``false`` otherwise.
|
|
||||||
var curve: cint
|
|
||||||
if len(data) > 0:
|
if len(data) > 0:
|
||||||
if len(data) == Sig256Length:
|
|
||||||
curve = cast[cint](Secp256r1)
|
|
||||||
result = true
|
|
||||||
elif len(data) == Sig384Length:
|
|
||||||
curve = cast[cint](Secp384r1)
|
|
||||||
result = true
|
|
||||||
elif len(data) == Sig521Length:
|
|
||||||
curve = cast[cint](Secp521r1)
|
|
||||||
result = true
|
|
||||||
if result:
|
|
||||||
sig = new EcSignature
|
sig = new EcSignature
|
||||||
sig.curve = curve
|
|
||||||
sig.buffer = @data
|
sig.buffer = @data
|
||||||
result = true
|
result = Asn1Status.Success
|
||||||
|
|
||||||
proc init*[T: EcPKI](sospk: var T, data: string): bool {.inline.} =
|
proc init*[T: EcPKI](sospk: var T, data: string): Asn1Status {.inline.} =
|
||||||
## Initialize EC `private key`, `public key` or `scalar` ``sospk`` from
|
## Initialize EC `private key`, `public key` or `scalar` ``sospk`` from
|
||||||
## hexadecimal string representation ``data``.
|
## hexadecimal string representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns ``true`` on success, ``false`` otherwise.
|
## Procedure returns ``Asn1Status``.
|
||||||
result = sospk.init(fromHex(data))
|
result = sospk.init(fromHex(data))
|
||||||
|
|
||||||
proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcPrivateKey =
|
proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcPrivateKey =
|
||||||
|
@ -589,8 +569,10 @@ proc init*(t: typedesc[EcPublicKey], data: openarray[byte]): EcPublicKey =
|
||||||
proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcSignature =
|
proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcSignature =
|
||||||
## Initialize EC signature from raw binary representation ``data`` and
|
## Initialize EC signature from raw binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
if not result.init(data):
|
let res = result.init(data)
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect signature")
|
if res != Asn1Status.Success:
|
||||||
|
raise newException(EcKeyIncorrectError,
|
||||||
|
"Incorrect signature (" & $res & ")")
|
||||||
|
|
||||||
proc init*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
|
proc init*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
|
||||||
## Initialize EC `private key`, `public key` or `scalar` from hexadecimal
|
## Initialize EC `private key`, `public key` or `scalar` from hexadecimal
|
||||||
|
@ -620,30 +602,30 @@ proc scalarMul*(pub: EcPublicKey, sec: EcPrivateKey): EcPublicKey =
|
||||||
|
|
||||||
proc sign*[T: byte|char](seckey: EcPrivateKey,
|
proc sign*[T: byte|char](seckey: EcPrivateKey,
|
||||||
message: openarray[T]): EcSignature =
|
message: openarray[T]): EcSignature =
|
||||||
## Get ECDSA signature of data ``message`` using private key ``seckey``.
|
## Get ECDSA signature of data ``message`` using private key ``seckey`` and.
|
||||||
var hc: BrHashCompatContext
|
var hc: BrHashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
var impl = brEcGetDefault()
|
var impl = brEcGetDefault()
|
||||||
if len(message) > 0:
|
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
let length = getSignatureLength(cast[EcCurveKind](seckey.key.curve))
|
|
||||||
result = new EcSignature
|
result = new EcSignature
|
||||||
result.curve = seckey.key.curve
|
result.buffer = newSeq[byte](256)
|
||||||
result.buffer = newSeq[byte](length)
|
|
||||||
var kv = addr sha256Vtable
|
var kv = addr sha256Vtable
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
|
if len(message) > 0:
|
||||||
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
||||||
|
else:
|
||||||
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.output(addr hc.vtable, addr hash[0])
|
||||||
let res = brEcdsaSignRaw(impl, kv, addr hash[0], addr seckey.key,
|
let res = brEcdsaSignAsn1(impl, kv, addr hash[0], addr seckey.key,
|
||||||
addr result.buffer[0])
|
addr result.buffer[0])
|
||||||
if res != getSignatureLength(cast[EcCurveKind](result.curve)):
|
|
||||||
raise newException(EcSignatureError, "Could not make signature")
|
|
||||||
# Clear context with initial value
|
# Clear context with initial value
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
|
if res != 0:
|
||||||
|
result.buffer.setLen(res)
|
||||||
|
else:
|
||||||
|
raise newException(EcSignatureError, "Could not make signature")
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
||||||
else:
|
|
||||||
raise newException(EcSignatureError, "Empty message")
|
|
||||||
|
|
||||||
proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
|
proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
|
||||||
pubkey: EcPublicKey): bool {.inline.} =
|
pubkey: EcPublicKey): bool {.inline.} =
|
||||||
|
@ -655,32 +637,17 @@ proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
|
||||||
var hc: BrHashCompatContext
|
var hc: BrHashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
var impl = brEcGetDefault()
|
var impl = brEcGetDefault()
|
||||||
if len(message) > 0:
|
if pubkey.key.curve in EcSupportedCurvesCint:
|
||||||
if pubkey.key.curve in EcSupportedCurvesCint and
|
|
||||||
pubkey.key.curve == sig.curve:
|
|
||||||
var kv = addr sha256Vtable
|
var kv = addr sha256Vtable
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
|
if len(message) > 0:
|
||||||
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
||||||
|
else:
|
||||||
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.output(addr hc.vtable, addr hash[0])
|
||||||
let res = brEcdsaVerifyRaw(impl, addr hash[0], 32, unsafeAddr pubkey.key,
|
let res = brEcdsaVerifyAsn1(impl, addr hash[0], len(hash),
|
||||||
|
unsafeAddr pubkey.key,
|
||||||
addr sig.buffer[0], len(sig.buffer))
|
addr sig.buffer[0], len(sig.buffer))
|
||||||
# Clear context with initial value
|
# Clear context with initial value
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
result = (res == 1)
|
result = (res == 1)
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
var buffer = newSeq[byte]()
|
|
||||||
var kp = EcKeyPair.random(Secp256r1)
|
|
||||||
var length: int
|
|
||||||
|
|
||||||
var serializedSK = kp.seckey.getBytes()
|
|
||||||
var serializedPK = kp.pubkey.getBytes()
|
|
||||||
echo toHex(serializedPK)
|
|
||||||
echo toHex(serializedSK)
|
|
||||||
|
|
||||||
var kp2 = EcPrivateKey.init(serializedSK)
|
|
||||||
echo toHex(kp2.getBytes())
|
|
||||||
|
|
||||||
var pk2 = EcPublicKey.init(serializedPK)
|
|
||||||
echo repr pk2
|
|
||||||
echo toHex(pk2.getBytes())
|
|
||||||
|
|
|
@ -0,0 +1,499 @@
|
||||||
|
## Nim-Libp2p
|
||||||
|
## Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
## Licensed under either of
|
||||||
|
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
|
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
## at your option.
|
||||||
|
## This file may not be copied, modified, or distributed except according to
|
||||||
|
## those terms.
|
||||||
|
import unittest
|
||||||
|
import nimcrypto/utils
|
||||||
|
import ../libp2p/crypto/ecnist
|
||||||
|
|
||||||
|
const
|
||||||
|
TestsCount = 10 # number of random tests
|
||||||
|
|
||||||
|
# Test vectors obtained from BearSSL test vectors (test_crypto.c) by
|
||||||
|
# conversion of raw values to ASN.1 DER binary encoded form.
|
||||||
|
SignatureSecKeys = [
|
||||||
|
"""30770201010420C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B
|
||||||
|
8A622B120F6721A00A06082A8648CE3D030107A1440342000460FED4BA255A9D
|
||||||
|
31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008B8BC
|
||||||
|
99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299""",
|
||||||
|
"""30770201010420C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B
|
||||||
|
8A622B120F6721A00A06082A8648CE3D030107A1440342000460FED4BA255A9D
|
||||||
|
31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008B8BC
|
||||||
|
99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299""",
|
||||||
|
"""3081A402010104306B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA
|
||||||
|
9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5A00706052B810400
|
||||||
|
22A16403620004EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06
|
||||||
|
AAE5286B300C64DEF8F0EA9055866064A254515480BC138015D9B72D7D57244E
|
||||||
|
A8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE73
|
||||||
|
44FD2533264720""",
|
||||||
|
"""3081A402010104306B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA
|
||||||
|
9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5A00706052B810400
|
||||||
|
22A16403620004EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06
|
||||||
|
AAE5286B300C64DEF8F0EA9055866064A254515480BC138015D9B72D7D57244E
|
||||||
|
A8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE73
|
||||||
|
44FD2533264720""",
|
||||||
|
"""3081DC020101044200FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018F
|
||||||
|
EE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB
|
||||||
|
89EC0C08B0E996B83538A00706052B81040023A18189038186000401894550D0
|
||||||
|
785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E
|
||||||
|
45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4004931
|
||||||
|
01C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB
|
||||||
|
25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5""",
|
||||||
|
"""3081DC020101044200FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018F
|
||||||
|
EE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB
|
||||||
|
89EC0C08B0E996B83538A00706052B81040023A18189038186000401894550D0
|
||||||
|
785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E
|
||||||
|
45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4004931
|
||||||
|
01C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB
|
||||||
|
25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5"""
|
||||||
|
]
|
||||||
|
|
||||||
|
SignaturePubKeys = [
|
||||||
|
"""3059301306072A8648CE3D020106082A8648CE3D0301070342000460FED4BA25
|
||||||
|
5A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008
|
||||||
|
B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299""",
|
||||||
|
"""3059301306072A8648CE3D020106082A8648CE3D0301070342000460FED4BA25
|
||||||
|
5A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008
|
||||||
|
B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299""",
|
||||||
|
"""3076301006072A8648CE3D020106052B8104002203620004EC3A4E415B4E19A4
|
||||||
|
568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA90558660
|
||||||
|
64A254515480BC138015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9
|
||||||
|
F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720""",
|
||||||
|
"""3076301006072A8648CE3D020106052B8104002203620004EC3A4E415B4E19A4
|
||||||
|
568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA90558660
|
||||||
|
64A254515480BC138015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9
|
||||||
|
F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720""",
|
||||||
|
"""30819B301006072A8648CE3D020106052B81040023038186000401894550D078
|
||||||
|
5932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45
|
||||||
|
DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A400493101
|
||||||
|
C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25
|
||||||
|
741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5""",
|
||||||
|
"""30819B301006072A8648CE3D020106052B81040023038186000401894550D078
|
||||||
|
5932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45
|
||||||
|
DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A400493101
|
||||||
|
C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25
|
||||||
|
741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5"""
|
||||||
|
]
|
||||||
|
|
||||||
|
SignatureMessages = [
|
||||||
|
"sample", "test", "sample", "test", "sample", "test"
|
||||||
|
]
|
||||||
|
|
||||||
|
SignatureVectors = [
|
||||||
|
"""3046022100EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0E
|
||||||
|
A84EAF3716022100F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF406
|
||||||
|
4DC4AB2F843ACDA8""",
|
||||||
|
"""3045022100F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3
|
||||||
|
B0B7D383670220019F4113742A2B14BD25926B49C649155F267E60D3814B4C0C
|
||||||
|
C84250E46F0083""",
|
||||||
|
"""3065023021B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A2
|
||||||
|
1D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD023100F3AA443FB107745BF4
|
||||||
|
BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0
|
||||||
|
CB8668A4FA0AB0""",
|
||||||
|
"""306402306D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB5
|
||||||
|
1D451559F918EEDAF2293BE5B475CC8F0188636B02302D46F3BECBCC523D5F1A
|
||||||
|
1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D51AB373F9845C0514EEF
|
||||||
|
B14024787265""",
|
||||||
|
"""308187024201511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92
|
||||||
|
B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D549728104
|
||||||
|
21E7D87589E1A702414A171143A83163D6DF460AAF61522695F207A58B95C064
|
||||||
|
4D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B
|
||||||
|
931F7DE6C9D949A7ECFC""",
|
||||||
|
"""30818702410E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B
|
||||||
|
41D8071042EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76
|
||||||
|
E6F1E4656AA8024200CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC64
|
||||||
|
4766CA14DA8CA5CA9FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619B
|
||||||
|
FBC828E7769BCD694E86"""
|
||||||
|
]
|
||||||
|
|
||||||
|
# This test vectors was generated using Go `crypto/ecdsa.go`.
|
||||||
|
# Its non-deterministic ECDSA signatures.
|
||||||
|
|
||||||
|
NDPrivateKeys = [
|
||||||
|
"""3077020101042068A2F6BCCA486C323C883328D890BA1C64A0B0CC9A8527D681
|
||||||
|
0AE8FDBB1B695CA00A06082A8648CE3D030107A144034200048EA1E33E80527E
|
||||||
|
FCAFB3E8924DD0CB3CF37DC406C65F6D69D6117B3F08A51E5280E2FE8AFAB32A
|
||||||
|
3EB1F4701BC7171FA62DDF46764A00E4024F286EADF3691FA0""",
|
||||||
|
"""3081A402010104301BC69416E84B85827018F7FC9EFCB6E426C1369ECA33CF45
|
||||||
|
10DBE38E065D5F78CB8F75185DCF2DBF5E239F18C424CF23A00706052B810400
|
||||||
|
22A164036200040B63293E10AE9348832D96F3EC1A4789D7F4F3F4F16E119E52
|
||||||
|
4227768FED3787D2FDEE6F4B9F2749EDBF4A0F1F72CACD1C7B3E9A7E2BD6E611
|
||||||
|
90D71133C55E479D7F73EECD73CE9BF471CDDAE9C234F394FAC6258E3B877FE2
|
||||||
|
5D6397D4B266CD""",
|
||||||
|
"""3081DC020101044201251023BBE7AA0121F34F39BD409021C4C3BB323E4729BF
|
||||||
|
D6842103C5628EC88F081BD01A8B27F25268CB4CFE46AE2741925EBCA3FA95C1
|
||||||
|
2A6D32AF161AEE2DB806A00706052B81040023A18189038186000400887F1A85
|
||||||
|
48791B40C677D80E70F5DFE84B50F301C4067222BDF1EE75B805227287A309C2
|
||||||
|
0C7E33E6FE93F651D6ABCE76E644DC16B220E34E68DCB5858262B00A07015923
|
||||||
|
7B66B29CABBDC352420E3652F6DCF6EB4EC6E08B0957EDC9ACC35CD684B99A78
|
||||||
|
E638C7937608749855C98C147DD46EE776234BA781D31C4FB05BB1D3648027"""
|
||||||
|
]
|
||||||
|
|
||||||
|
NDPublicKeys = [
|
||||||
|
"""3059301306072A8648CE3D020106082A8648CE3D030107034200048EA1E33E80
|
||||||
|
527EFCAFB3E8924DD0CB3CF37DC406C65F6D69D6117B3F08A51E5280E2FE8AFA
|
||||||
|
B32A3EB1F4701BC7171FA62DDF46764A00E4024F286EADF3691FA0""",
|
||||||
|
"""3076301006072A8648CE3D020106052B81040022036200040B63293E10AE9348
|
||||||
|
832D96F3EC1A4789D7F4F3F4F16E119E524227768FED3787D2FDEE6F4B9F2749
|
||||||
|
EDBF4A0F1F72CACD1C7B3E9A7E2BD6E61190D71133C55E479D7F73EECD73CE9B
|
||||||
|
F471CDDAE9C234F394FAC6258E3B877FE25D6397D4B266CD""",
|
||||||
|
"""30819B301006072A8648CE3D020106052B81040023038186000400887F1A8548
|
||||||
|
791B40C677D80E70F5DFE84B50F301C4067222BDF1EE75B805227287A309C20C
|
||||||
|
7E33E6FE93F651D6ABCE76E644DC16B220E34E68DCB5858262B00A070159237B
|
||||||
|
66B29CABBDC352420E3652F6DCF6EB4EC6E08B0957EDC9ACC35CD684B99A78E6
|
||||||
|
38C7937608749855C98C147DD46EE776234BA781D31C4FB05BB1D3648027"""
|
||||||
|
]
|
||||||
|
|
||||||
|
NDMessages = [
|
||||||
|
"sample", "sample", "sample", "test", "test", "test",
|
||||||
|
"sample", "sample", "sample", "test", "test", "test",
|
||||||
|
"sample", "sample", "sample", "test", "test", "test",
|
||||||
|
]
|
||||||
|
|
||||||
|
NDSignatures = [
|
||||||
|
"""304502210088C7E8176CBA8EBE0672391AB698101FC78F187AE029ACF7EA846633
|
||||||
|
2892B59B022078DA1A6792B7450084085881A482313C846F66162C15D9B50CBC2F
|
||||||
|
19427ACC9C""",
|
||||||
|
"""30450221008C4CD62BB25709AE0F060AAACF6FE63B87FACE3DA2B77EE545AC2289
|
||||||
|
7E250897022060A59D99C681DD736A6C18DC4ABF3635E749886A748908CB4E8E77
|
||||||
|
457212FC47""",
|
||||||
|
"""3046022100F86C58A4607DDBD3E2C780B4FCB64848F9216D22FFBCE898BA8F9D05
|
||||||
|
3EAF656E022100A5C2688897C0CC471602FF86D445B09EFB12EC64C75D9096A528
|
||||||
|
1D90948952DE""",
|
||||||
|
"""304402206CCE912F77B6E20709CD2A7D7C5E046674DBC958C247B1E3F7AEC766CF
|
||||||
|
A8EF72022056BF2A26EBD7AE4DA3080C75A2B2F247A941B87C941DC91F4FCBF19C
|
||||||
|
8B106DEC""",
|
||||||
|
"""3046022100D940CBF42025B33E23C67390CBF160F78A6FE76DA6721F6551F4CA67
|
||||||
|
E0C8D88D022100B51E501945EF340DBB5440D44242E71F67835E5B46C5F3E19FB8
|
||||||
|
F5C24F036DA2""",
|
||||||
|
"""3045022100A6BE7BADFD38D2ABEF78CE48471DA0D6580E33C2BAF4B48D1155247D
|
||||||
|
B5645E1E02206505D23CD41C10D1E55878FD9CF4072420F2DF7212728604F72DC2
|
||||||
|
B1BB8DFAB0""",
|
||||||
|
"""306402307566A2ACC93DF36170A0A2A98CA18A979E5F3052488FAA272DDEE8306A
|
||||||
|
CD6B48259E2BE3170346D3EFAA69B973909BA702300B066D618D3D1FB61328594B
|
||||||
|
79C45F1AAE4F8C99F8FAED79A9ED8C729BC1932F11E5D05A4410FABF394CCFC6AA
|
||||||
|
9A6AB9""",
|
||||||
|
"""3066023100AF3FCC8CCF5B2256ABF638BC18001985F4A8D9845EC6E1BE8E708D21
|
||||||
|
E60256E8CD00833EFC0F2E793BDC9B433482A09A023100DBA731B3D6B14CE8EE96
|
||||||
|
EDC083B97A01CE46A4B2F0583FCB9A2B7F12AC62985942DF386579E2CBBAF75C90
|
||||||
|
C468B7D1CB""",
|
||||||
|
"""3065023100E9022EB07F766FCC68D345CF758FBC54EFCAC086CD8625DFDE588F67
|
||||||
|
D06A4357DE5F9ED39298F5D9299C7AB24E6E5984023006838D2A052990DB3A5BCC
|
||||||
|
12CAE45863DEC9023625C12D143DD4F75FCC50625FB35108BA2090C1FCAC48353F
|
||||||
|
54A03021""",
|
||||||
|
"""3066023100C77C91B69D2064DD312A149C8074DCAC7FC734EB70AF3FF52F7F7D6E
|
||||||
|
4253C163FF1A574ADC30C58DDD58CF06F883B880023100F780E8D1F094F6112EC7
|
||||||
|
8317CF1BDEB068D1BB472D8CB6E49A707409F0A22C867A254EE80F8949260E31AB
|
||||||
|
5AF9AD4060""",
|
||||||
|
"""3065023100D9027A9485BAB5BE90F2D9FCB14A494CA8B829C7A815F40DD17235D2
|
||||||
|
4296927122CBC11A1417D9856E815DF81AF3950202305A617D78CEA2586A55EB85
|
||||||
|
63B3563385753A6F84D2AF02C61F889DF6EDD6F1D0A3DE07BD859D7CB1D8264726
|
||||||
|
696130D6""",
|
||||||
|
"""306502307F476CBE232E1BFED31061713B5611852B730ACB4053C6AB2D85C4563A
|
||||||
|
581A773B4A76F65D8DDB76D09BC038AEB3B2AC023100C778A6DCB18451A251DD9D
|
||||||
|
BD55F18CC45FAC16EA458270A6C7B8E0D7BC91264C66CDDB8013C17EC98365B0FA
|
||||||
|
6B0049AA""",
|
||||||
|
"""30818802420137C1D1943C9ABCA116D87B46C2D7A146AE358F1378ACA58D405735
|
||||||
|
20B6BEDECDC500EF9172B363B862734C528ED01484822E168FB6BFDB2342A0AB45
|
||||||
|
8DD3B7BB8B024200FEDC89C8BF2611ABD27FDAD58E5DAAC9DD744D744017E29002
|
||||||
|
573D0F6F8A6B13D6901ADC07D5C6D1746910340D8C2C0D6109F939C0172D1F229A
|
||||||
|
818E0C6643E774""",
|
||||||
|
"""3081880242012173FFB97D1318F53F50818DAADB5B600ED928F39CD98F712C44BB
|
||||||
|
810AB4EE74D02C385DFEBEFCC2DC56DE4EB2794681EC0345B170C3BEFCDF2A1693
|
||||||
|
9DC6DDF58D024201724AB5BED8F88B30E84CB0A2ED4BDD12EB2222C9E4FC0897B9
|
||||||
|
4390FD44FFE118A7EDB948E1AB7FDB1A19C920A4160DA4596DA5D2731D10143DE5
|
||||||
|
103FFF93A51EF6""",
|
||||||
|
"""30818602416BADAFFFF67959764ADC0F45AB0911DE85D0FC0608A0AD60C14456E1
|
||||||
|
01CBF51CBBEB9D0B2E71EBE3EC1B4D45851ED71CAFE0A83DF593C803350A6BB36E
|
||||||
|
0EB18A21024169E20B6463357D4363BE05DF3B4FF5BC21FFAC652C7005E0314A3D
|
||||||
|
A443D3B537608139CE14A94C7C3A53063910F1062E385A4464022C5E662CC53833
|
||||||
|
EB870435E2""",
|
||||||
|
"""308187024158F13B64E188FF6BB766D129E087420D2070752D1E1F29BF64EE13C9
|
||||||
|
5FF222D7E5DF595EC21FED066A83C0027CE60C1A7BD92B4641E34CBB34ECFDE5F6
|
||||||
|
6762659D024201105D3482639186FC0322933998FE0E71E0BA359ED9BB8DE127E5
|
||||||
|
73A88311F735FFD87CF279B667A2AF681122EDA9F7FC7784E0E942A287C917C7EC
|
||||||
|
DFE2F8E6368C""",
|
||||||
|
"""30818802420145D48CA13B92808CAA7959574CDACF9959ED72A9ADC6FFCA0FD417
|
||||||
|
0F2EFD854C8C479099F0784D717A56EC9F5777A0096CD251F96F2CCB6061D2C8CA
|
||||||
|
CD09EB606C0242011683C215C7DE99E3D4FF8D543C6CFDCC49577A8978D10C818C
|
||||||
|
002A51D7C8D7FBC1814D82EDA9521F19C8895DCE6CAE97F8926CCCE3863D5E120F
|
||||||
|
77B6D2C891AB7F""",
|
||||||
|
"""308187024200F235341F4C39641FFBA7FFB1551C36E34F606F4C2970DE00096A37
|
||||||
|
722D83D07D0ADFB3D33492F2645B15A19FFAF6424A03487CE2E099069006037956
|
||||||
|
9972DC798A02412B6F169D23303B0C7764620514EF308F010EFB4E3A69912967EE
|
||||||
|
303B177FA12B58C4602183BCB58D5DB30917584EDFE4BE4B42EC0EE3E3FB75BDA8
|
||||||
|
C05CB9C3A2DA"""
|
||||||
|
]
|
||||||
|
|
||||||
|
suite "EC NIST-P256/384/521 test suite":
|
||||||
|
|
||||||
|
test "[secp256r1] Private key serialize/deserialize test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var rkey1, rkey2: EcPrivateKey
|
||||||
|
var skey2 = newSeq[byte](256)
|
||||||
|
var key = EcPrivateKey.random(Secp256r1)
|
||||||
|
var skey1 = key.getBytes()
|
||||||
|
check:
|
||||||
|
key.toBytes(skey2) > 0
|
||||||
|
check:
|
||||||
|
rkey1.init(skey1) == Asn1Status.Success
|
||||||
|
rkey2.init(skey2) == Asn1Status.Success
|
||||||
|
var rkey3 = EcPrivateKey.init(skey1)
|
||||||
|
var rkey4 = EcPrivateKey.init(skey2)
|
||||||
|
check:
|
||||||
|
rkey1 == key
|
||||||
|
rkey2 == key
|
||||||
|
rkey3 == key
|
||||||
|
rkey4 == key
|
||||||
|
|
||||||
|
test "[secp256r1] Public key serialize/deserialize test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var rkey1, rkey2: EcPublicKey
|
||||||
|
var skey2 = newSeq[byte](256)
|
||||||
|
var pair = EcKeyPair.random(Secp256r1)
|
||||||
|
var skey1 = pair.pubkey.getBytes()
|
||||||
|
check:
|
||||||
|
pair.pubkey.toBytes(skey2) > 0
|
||||||
|
rkey1.init(skey1) == Asn1Status.Success
|
||||||
|
rkey2.init(skey2) == Asn1Status.Success
|
||||||
|
var rkey3 = EcPublicKey.init(skey1)
|
||||||
|
var rkey4 = EcPublicKey.init(skey2)
|
||||||
|
check:
|
||||||
|
rkey1 == pair.pubkey
|
||||||
|
rkey2 == pair.pubkey
|
||||||
|
rkey3 == pair.pubkey
|
||||||
|
rkey4 == pair.pubkey
|
||||||
|
|
||||||
|
test "[secp256r1] ECDHE test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var kp1 = EcKeyPair.random(Secp256r1)
|
||||||
|
var kp2 = EcKeyPair.random(Secp256r1)
|
||||||
|
var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
|
||||||
|
var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
|
||||||
|
check:
|
||||||
|
isNil(shared1) == false
|
||||||
|
isNil(shared2) == false
|
||||||
|
shared1 == shared2
|
||||||
|
|
||||||
|
test "[secp256r1] ECDSA test vectors":
|
||||||
|
for i in 0..<2:
|
||||||
|
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
|
||||||
|
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
|
||||||
|
var checkpk = sk.getKey()
|
||||||
|
check expectpk == checkpk
|
||||||
|
var checksig = sk.sign(SignatureMessages[i])
|
||||||
|
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
|
||||||
|
check:
|
||||||
|
checksig == expectsig
|
||||||
|
checksig.verify(SignatureMessages[i], checkpk) == true
|
||||||
|
checksig.buffer[len(checksig.buffer) - 1] = 0x80'u8
|
||||||
|
check checksig.verify(SignatureMessages[i], checkpk) == false
|
||||||
|
|
||||||
|
test "[secp256r1] ECDSA non-deterministic test vectors":
|
||||||
|
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[0]))
|
||||||
|
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[0]))
|
||||||
|
var checkpk = sk.getKey()
|
||||||
|
check pk == checkpk
|
||||||
|
for i in 0..<6:
|
||||||
|
var message = NDMessages[i]
|
||||||
|
var checksig = EcSignature.init(stripSpaces(NDSignatures[i]))
|
||||||
|
check checksig.verify(message, pk) == true
|
||||||
|
checksig.buffer[len(checksig.buffer) - 1] = 0x80'u8
|
||||||
|
check checksig.verify(message, pk) == false
|
||||||
|
|
||||||
|
test "[secp256r1] Generate/Sign/Serialize/Deserialize/Verify test":
|
||||||
|
var message = "message to sign"
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var kp = EcKeyPair.random(Secp256r1)
|
||||||
|
var sig = kp.seckey.sign(message)
|
||||||
|
var sersk = kp.seckey.getBytes()
|
||||||
|
var serpk = kp.pubkey.getBytes()
|
||||||
|
var sersig = sig.getBytes()
|
||||||
|
var seckey = EcPrivateKey.init(sersk)
|
||||||
|
var pubkey = EcPublicKey.init(serpk)
|
||||||
|
var csig = EcSignature.init(sersig)
|
||||||
|
check csig.verify(message, pubkey) == true
|
||||||
|
csig.buffer[len(csig.buffer) - 1] = 0x80'u8
|
||||||
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
|
test "[secp384r1] Private key serialize/deserialize test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var rkey1, rkey2: EcPrivateKey
|
||||||
|
var skey2 = newSeq[byte](256)
|
||||||
|
var key = EcPrivateKey.random(Secp384r1)
|
||||||
|
var skey1 = key.getBytes()
|
||||||
|
check:
|
||||||
|
key.toBytes(skey2) > 0
|
||||||
|
check:
|
||||||
|
rkey1.init(skey1) == Asn1Status.Success
|
||||||
|
rkey2.init(skey2) == Asn1Status.Success
|
||||||
|
var rkey3 = EcPrivateKey.init(skey1)
|
||||||
|
var rkey4 = EcPrivateKey.init(skey2)
|
||||||
|
check:
|
||||||
|
rkey1 == key
|
||||||
|
rkey2 == key
|
||||||
|
rkey3 == key
|
||||||
|
rkey4 == key
|
||||||
|
|
||||||
|
test "[secp384r1] Public key serialize/deserialize test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var rkey1, rkey2: EcPublicKey
|
||||||
|
var skey2 = newSeq[byte](256)
|
||||||
|
var pair = EcKeyPair.random(Secp384r1)
|
||||||
|
var skey1 = pair.pubkey.getBytes()
|
||||||
|
check:
|
||||||
|
pair.pubkey.toBytes(skey2) > 0
|
||||||
|
rkey1.init(skey1) == Asn1Status.Success
|
||||||
|
rkey2.init(skey2) == Asn1Status.Success
|
||||||
|
var rkey3 = EcPublicKey.init(skey1)
|
||||||
|
var rkey4 = EcPublicKey.init(skey2)
|
||||||
|
check:
|
||||||
|
rkey1 == pair.pubkey
|
||||||
|
rkey2 == pair.pubkey
|
||||||
|
rkey3 == pair.pubkey
|
||||||
|
rkey4 == pair.pubkey
|
||||||
|
|
||||||
|
test "[secp384r1] ECDHE test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var kp1 = EcKeyPair.random(Secp384r1)
|
||||||
|
var kp2 = EcKeyPair.random(Secp384r1)
|
||||||
|
var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
|
||||||
|
var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
|
||||||
|
check:
|
||||||
|
isNil(shared1) == false
|
||||||
|
isNil(shared2) == false
|
||||||
|
shared1 == shared2
|
||||||
|
|
||||||
|
test "[secp384r1] ECDSA test vectors":
|
||||||
|
for i in 2..<4:
|
||||||
|
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
|
||||||
|
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
|
||||||
|
var checkpk = sk.getKey()
|
||||||
|
check expectpk == checkpk
|
||||||
|
var checksig = sk.sign(SignatureMessages[i])
|
||||||
|
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
|
||||||
|
check:
|
||||||
|
checksig == expectsig
|
||||||
|
checksig.verify(SignatureMessages[i], checkpk) == true
|
||||||
|
checksig.buffer[len(checksig.buffer) - 1] = 0x80'u8
|
||||||
|
check checksig.verify(SignatureMessages[i], checkpk) == false
|
||||||
|
|
||||||
|
test "[secp384r1] ECDSA non-deterministic test vectors":
|
||||||
|
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[1]))
|
||||||
|
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[1]))
|
||||||
|
var checkpk = sk.getKey()
|
||||||
|
check pk == checkpk
|
||||||
|
for i in 6..<12:
|
||||||
|
var message = NDMessages[i]
|
||||||
|
var checksig = EcSignature.init(stripSpaces(NDSignatures[i]))
|
||||||
|
check checksig.verify(message, pk) == true
|
||||||
|
checksig.buffer[len(checksig.buffer) - 1] = 0x80'u8
|
||||||
|
check checksig.verify(message, pk) == false
|
||||||
|
|
||||||
|
test "[secp384r1] Generate/Sign/Serialize/Deserialize/Verify test":
|
||||||
|
var message = "message to sign"
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var kp = EcKeyPair.random(Secp384r1)
|
||||||
|
var sig = kp.seckey.sign(message)
|
||||||
|
var sersk = kp.seckey.getBytes()
|
||||||
|
var serpk = kp.pubkey.getBytes()
|
||||||
|
var sersig = sig.getBytes()
|
||||||
|
var seckey = EcPrivateKey.init(sersk)
|
||||||
|
var pubkey = EcPublicKey.init(serpk)
|
||||||
|
var csig = EcSignature.init(sersig)
|
||||||
|
check csig.verify(message, pubkey) == true
|
||||||
|
csig.buffer[len(csig.buffer) - 1] = 0x80'u8
|
||||||
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
|
test "[secp521r1] Private key serialize/deserialize test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var rkey1, rkey2: EcPrivateKey
|
||||||
|
var skey2 = newSeq[byte](256)
|
||||||
|
var key = EcPrivateKey.random(Secp521r1)
|
||||||
|
var skey1 = key.getBytes()
|
||||||
|
check:
|
||||||
|
key.toBytes(skey2) > 0
|
||||||
|
check:
|
||||||
|
rkey1.init(skey1) == Asn1Status.Success
|
||||||
|
rkey2.init(skey2) == Asn1Status.Success
|
||||||
|
var rkey3 = EcPrivateKey.init(skey1)
|
||||||
|
var rkey4 = EcPrivateKey.init(skey2)
|
||||||
|
check:
|
||||||
|
rkey1 == key
|
||||||
|
rkey2 == key
|
||||||
|
rkey3 == key
|
||||||
|
rkey4 == key
|
||||||
|
|
||||||
|
test "[secp521r1] Public key serialize/deserialize test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var rkey1, rkey2: EcPublicKey
|
||||||
|
var skey2 = newSeq[byte](256)
|
||||||
|
var pair = EcKeyPair.random(Secp521r1)
|
||||||
|
var skey1 = pair.pubkey.getBytes()
|
||||||
|
check:
|
||||||
|
pair.pubkey.toBytes(skey2) > 0
|
||||||
|
rkey1.init(skey1) == Asn1Status.Success
|
||||||
|
rkey2.init(skey2) == Asn1Status.Success
|
||||||
|
var rkey3 = EcPublicKey.init(skey1)
|
||||||
|
var rkey4 = EcPublicKey.init(skey2)
|
||||||
|
check:
|
||||||
|
rkey1 == pair.pubkey
|
||||||
|
rkey2 == pair.pubkey
|
||||||
|
rkey3 == pair.pubkey
|
||||||
|
rkey4 == pair.pubkey
|
||||||
|
|
||||||
|
test "[secp521r1] ECDHE test":
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var kp1 = EcKeyPair.random(Secp521r1)
|
||||||
|
var kp2 = EcKeyPair.random(Secp521r1)
|
||||||
|
var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
|
||||||
|
var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
|
||||||
|
check:
|
||||||
|
isNil(shared1) == false
|
||||||
|
isNil(shared2) == false
|
||||||
|
shared1 == shared2
|
||||||
|
|
||||||
|
test "[secp521r1] ECDSA test vectors":
|
||||||
|
for i in 4..<6:
|
||||||
|
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
|
||||||
|
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
|
||||||
|
var checkpk = sk.getKey()
|
||||||
|
check expectpk == checkpk
|
||||||
|
var checksig = sk.sign(SignatureMessages[i])
|
||||||
|
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
|
||||||
|
check:
|
||||||
|
checksig == expectsig
|
||||||
|
checksig.verify(SignatureMessages[i], checkpk) == true
|
||||||
|
checksig.buffer[len(checksig.buffer) - 1] = 0x80'u8
|
||||||
|
check checksig.verify(SignatureMessages[i], checkpk) == false
|
||||||
|
|
||||||
|
test "[secp521r1] ECDSA non-deterministic test vectors":
|
||||||
|
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[2]))
|
||||||
|
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[2]))
|
||||||
|
var checkpk = sk.getKey()
|
||||||
|
check pk == checkpk
|
||||||
|
for i in 12..<18:
|
||||||
|
var message = NDMessages[i]
|
||||||
|
var checksig = EcSignature.init(stripSpaces(NDSignatures[i]))
|
||||||
|
check checksig.verify(message, pk) == true
|
||||||
|
checksig.buffer[len(checksig.buffer) - 1] = 0x80'u8
|
||||||
|
check checksig.verify(message, pk) == false
|
||||||
|
|
||||||
|
test "[secp521r1] Generate/Sign/Serialize/Deserialize/Verify test":
|
||||||
|
var message = "message to sign"
|
||||||
|
for i in 0..<TestsCount:
|
||||||
|
var kp = EcKeyPair.random(Secp521r1)
|
||||||
|
var sig = kp.seckey.sign(message)
|
||||||
|
var sersk = kp.seckey.getBytes()
|
||||||
|
var serpk = kp.pubkey.getBytes()
|
||||||
|
var sersig = sig.getBytes()
|
||||||
|
var seckey = EcPrivateKey.init(sersk)
|
||||||
|
var pubkey = EcPublicKey.init(serpk)
|
||||||
|
var csig = EcSignature.init(sersig)
|
||||||
|
check csig.verify(message, pubkey) == true
|
||||||
|
csig.buffer[len(csig.buffer) - 1] = 0x80'u8
|
||||||
|
check csig.verify(message, pubkey) == false
|
Loading…
Reference in New Issue