2016-01-20 03:18:27 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2016 Galois, Inc.
|
|
|
|
* Distributed under the terms of the BSD3 license (see LICENSE file)
|
|
|
|
*/
|
2016-01-20 00:47:35 +03:00
|
|
|
module Keys where
|
|
|
|
|
|
|
|
import CfrgCurves
|
|
|
|
import Blake2s
|
|
|
|
import SCrypt
|
|
|
|
import Base58
|
|
|
|
|
|
|
|
type MinilockID = [46][8]
|
|
|
|
|
|
|
|
// Given a public key compute the ASCII ID
|
|
|
|
encodeID : Public25519 -> MinilockID
|
|
|
|
encodeID pub = base58enc (join (pub # [h]))
|
|
|
|
where
|
|
|
|
h = blake2s `{nn=1} pub : [8]
|
|
|
|
|
|
|
|
decodeID : MinilockID -> (Bit,Public25519)
|
|
|
|
decodeID ident = (hComp == hRecv, key)
|
|
|
|
where
|
|
|
|
bs = split (base58dec ident) : [33][8]
|
|
|
|
hRecv = bs ! 0
|
|
|
|
hComp = blake2s `{nn=1} key : [8]
|
|
|
|
key = take bs : [32][8]
|
|
|
|
|
|
|
|
// Accept a possibly-short key (base58 is value dependent encoding)
|
|
|
|
// and expand it to the full, fixed, size.
|
|
|
|
mkFullLengthID : {n} (46 >= n, n>= 1) => [n][8] -> MinilockID
|
|
|
|
mkFullLengthID n = drop (['1' | _ <- [0..45] : [_][8]] # n)
|
|
|
|
|
|
|
|
mkID : {passBytes, saltBytes}
|
|
|
|
( fin passBytes, fin saltBytes
|
|
|
|
, 64 >= width passBytes
|
|
|
|
, 32 >= width (4*saltBytes)
|
|
|
|
)
|
|
|
|
=> [passBytes][8] -> [saltBytes][8] -> (MinilockID,Private25519)
|
|
|
|
mkID pw email = (encodeID pub,priv)
|
|
|
|
where
|
|
|
|
// XXX wait for cryptol 2.3: priv = SCrypt `{N=2^^17,r=8} (split (blake2s `{nn=32} pw)) email
|
|
|
|
priv : Private25519
|
|
|
|
priv = SCrypt `{N=2^^1,r=8} (split (blake2s `{nn=32} pw)) email
|
|
|
|
// XXX we can't interpret N=2^^17 so this N value is a place holder...
|
|
|
|
pub = Curve25519 priv basePoint25519
|
|
|
|
|
|
|
|
// XXX we can not run these tests in the cryptol interpreter, SCrypt is too expensive.
|
|
|
|
testPass = "some bears eat all the honey in the jar"
|
|
|
|
testEmail = "example@example.com"
|
|
|
|
|
|
|
|
testID : MinilockID
|
|
|
|
testID = mkFullLengthID "28ZvW9rqRqvqpFTtHnusUntRqrxb4qqZAaNAd3QsqjSsXq"
|
|
|
|
|
|
|
|
testID_computed = "28ZvW9rqRqvqpFTtHnusUntRqrxb4qqZAaNAd3QsqjSsXq" // Computed on deathstar
|
|
|
|
testPriv_computed =
|
|
|
|
[0x12, 0x86, 0xe0, 0x18, 0xc6, 0x68, 0x34, 0x96, 0x09, 0x2e, 0x53,
|
|
|
|
0x32, 0x37, 0x76, 0x80, 0x3c, 0x30, 0xb4, 0x75, 0x2d, 0xd7, 0x70,
|
|
|
|
0xea, 0xa9, 0x6f, 0x0d, 0xda, 0x25, 0xc7, 0xfe, 0x28, 0x1f]
|
|
|
|
|
|
|
|
// Deathstar results:
|
|
|
|
// ([0x32, 0x38, 0x5a, 0x76, 0x57, 0x39, 0x72, 0x71, 0x52, 0x71, 0x76,
|
|
|
|
// 0x71, 0x70, 0x46, 0x54, 0x74, 0x48, 0x6e, 0x75, 0x73, 0x55, 0x6e,
|
|
|
|
// 0x74, 0x52, 0x71, 0x72, 0x78, 0x62, 0x34, 0x71, 0x71, 0x5a, 0x41,
|
|
|
|
// 0x61, 0x4e, 0x41, 0x64, 0x33, 0x51, 0x73, 0x71, 0x6a, 0x53, 0x73,
|
|
|
|
// 0x58, 0x71],
|
|
|
|
// [0x12, 0x86, 0xe0, 0x18, 0xc6, 0x68, 0x34, 0x96, 0x09, 0x2e, 0x53,
|
|
|
|
// 0x32, 0x37, 0x76, 0x80, 0x3c, 0x30, 0xb4, 0x75, 0x2d, 0xd7, 0x70,
|
|
|
|
// 0xea, 0xa9, 0x6f, 0x0d, 0xda, 0x25, 0xc7, 0xfe, 0x28, 0x1f])
|
|
|
|
|
|
|
|
|
|
|
|
// testPriv : Private25519
|
|
|
|
testPriv = [0x12, 0x86, 0xe0, 0x18, 0xc6, 0x68, 0x34, 0x96, 0x09, 0x2e, 0x53, 0x32, 0x37, 0x76, 0x80, 0x3c, 0x30, 0xb4, 0x75, 0x2d, 0xd7, 0x70,0xea, 0xa9, 0x6f, 0x0d, 0xda, 0x25, 0xc7, 0xfe, 0x28, 0x1f]
|
|
|
|
|
|
|
|
testPub = Curve25519 testPriv basePoint25519
|
2016-08-23 04:14:44 +03:00
|
|
|
property kat_pub_id_eq = testPub == (decodeID testID).1 /\ encodeID testPub == testID /\ testID == testID_computed /\ testPriv == testPriv_computed
|