Release 0.9.0-SNAPSHOT with concealed KMP transports
This commit is contained in:
1 parent
009d62a155
commit
73a785d45c
55 files changed
+6051
-25
No files matched your search
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"serverSecret": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"serverPublic": "8f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f",
|
||||
"clientDhSecret": "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
|
||||
"clientDhPublic": "358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254",
|
||||
"serverDhSecret": "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
|
||||
"serverDhPublic": "79a631eede1bf9c98f12032cdeadd0e7a079398fc786b88cc846ec89af85a51a",
|
||||
"serverSigningSeed": "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f",
|
||||
"serverIdentity": "174553b456dddfc6908ecab1c101fe6ab21e2baa0617795b7d43a63482993fd5",
|
||||
"clientSigningSeed": "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
"clientIdentity": "cd14b37f956e953194ff7fb73b3d81dcc561d61a7538094b7c3e1a643ee5f3aa",
|
||||
"representative": "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf",
|
||||
"heloIv": "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7",
|
||||
"bootstrapShared": "900702f8b7a7dd869cf98f17dce31515a39e8043636352e8bf7be99043b83101",
|
||||
"bootstrapRoot": "f0cce9735754e6985895bbf2ad73a16a1ad5732399df991a598f17e71f3b2d04",
|
||||
"heloCore": "0101358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254174553b456dddfc6908ecab1c101fe6ab21e2baa0617795b7d43a63482993fd500100000000000000000",
|
||||
"f1": "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d77e7c60745d6ff2d29cb31ea1ee07d57dcbf42a3b1ac4341763a6f7baaa5766561e2fd98b7e4a69846548854a72be3b036eac464732b81a97afd4ef73c75f0a45703fd77c5ee8d29188ea452d9125e0bd8b798c212fccb1a65b4b617c1ebffd3c10256bc31f2949c6095f8cbc241d43b12f1591d01df46548",
|
||||
"h1": "602f30edcbbd47efaeaf6c79e30d0a418ac5dd0f18f03148dc55d6f1115ac6c1",
|
||||
"replyIv": "000102030405060708090a0b0c0d0e0f1011121314151617",
|
||||
"replyRoot": "7b747b6d95ad2bbb29d75ffd307291a1fbe9ac30e29fd8723ad859c7edd9cd50",
|
||||
"serverCore": "010179a631eede1bf9c98f12032cdeadd0e7a079398fc786b88cc846ec89af85a51a56a735db2bdb65b5240a7c7265917a909c1515ca682dcce740c9f00ac91eabcd174553b456dddfc6908ecab1c101fe6ab21e2baa0617795b7d43a63482993fd500100000000000000000",
|
||||
"serverSignature": "c9449226a851142979083bb1c633005c6323be2c868b2c188db04e63c9dd8952f1bfb549b4a43fa485cf456fe139206f92adf8a738e1ca4d95f03b0378d22906",
|
||||
"f2": "000102030405060708090a0b0c0d0e0f10111213141516179e23f0972e103c06d5b5a374b83490d3746d51aeb4efb24829822dc8a6826e417734a39ad43437e12d7e379cf633d2397a9ede00b477308a59f262f12c0804f79b7b00b86f04426c7349d53d4935601dad6eb81a95e0bbdab3d73607a6187e2bd18a83d90c93858f17dee1753cfb56395c505a004fc1cbcc2ca6c3820c81b3128c8f69138e7435dfba773b8a05cfa7a328d4bc76dd0db0aba878718c48798ee60a95cb46d24d87003a688e0eb3761871f33621b245f70d1152358cbc41e7b073de23d41579f81883725035a46248c1c17a59644e43ac9e6a",
|
||||
"h2": "ccb3ed241a73bd60911c36356a70651e8ab884ed5958514122f35d382d0d2533",
|
||||
"sessionShared": "04c304fb1ca83cee75e206344231f33797e07d9929db670994b7c6fbeb1dc255",
|
||||
"s2c": "46d6c3a94b432fab260e6252e53b488c6ce8b5dca9d17499facac2e402f1ccb1",
|
||||
"c2s": "2839576c1187d37c4e4d330ce4331c305c9ebf1ac599110fd1e9c44c1f64a5f3",
|
||||
"token": "b6e3c9512701a9edea03d60c5f50ac894bf652c776e3636f642a319357148481",
|
||||
"finishedC2s": "4e6ed04a46d1f01c64873c0050afb167b110de66ae8ab97344e79d0c527bd8ad",
|
||||
"finishedS2c": "f6de33390f63d704bf2fa82dac7aa1e21a08da48351326047d68c6dd6c9d280e",
|
||||
"clientSignature": "dc405b92ddf7499d47f3a32e837bed640d4565632e4f332ccbc7b6159a0afd1e1272bd36531a6b5d8a40c60e4a307b8a8e8aca62ba4d635ba278b19e5c448004",
|
||||
"ackCore": "03ccb3ed241a73bd60911c36356a70651e8ab884ed5958514122f35d382d0d2533cd14b37f956e953194ff7fb73b3d81dcc561d61a7538094b7c3e1a643ee5f3aadc405b92ddf7499d47f3a32e837bed640d4565632e4f332ccbc7b6159a0afd1e1272bd36531a6b5d8a40c60e4a307b8a8e8aca62ba4d635ba278b19e5c448004",
|
||||
"ackIv": "18191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f",
|
||||
"f3": "18191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f13d609bbf798a1056e5bca20eb89872e2160808864b58cf718c89dabe170b453ccfff09a287502ab1167011f79bbcdabdd673a8e26b22f4f7e7d91ec802dc1b8917820d93a24faaa86abfd0c04ec6c670a5938ac8e003aa7378e6a995b3039e7d5d1a0dd233c8589feb771ee1a6df8d8e43a6ace5ce146ca440eaaa0c3ff0cfe190be2dd60a9c129ae4cb5e3802fd306e1086a180605c59c01e1a17ffb943e517a6516f409159b1b6a9ce95079",
|
||||
"h3": "4f21ca3091f37bf39d78fea6cb5ea6dca91f0fd78442beb6874fc6a9097be5c0",
|
||||
"acceptCore": "044f21ca3091f37bf39d78fea6cb5ea6dca91f0fd78442beb6874fc6a9097be5c0",
|
||||
"acceptIv": "303132333435363738393a3b3c3d3e3f4041424344454647",
|
||||
"f4": "303132333435363738393a3b3c3d3e3f40414243444546479c1359d7f05d126e96c469773c8a586c711742c1547137a75fed8f3e29c2bb51cf8e86698471e4e4ab58e325efe7c451c6183ae167602430d9a9773baec43dccd6d4d4c067b012838fabaf7624",
|
||||
"c2sStreamKey": "3849e6ec55adeb429a2f1152fe1d6499f3c331d0c20f961ffb07d37d0a1f6ba6",
|
||||
"c2sStreamSalt": "124c709383f7fec219af21b040cafa2c28ee23b58bdbd36e",
|
||||
"c2sMacKey": "098146c2016cc5d4799e804784c424746b75b4f0dfe5ad6772147f48424cfafe",
|
||||
"c2sUdpKey": "e39c67192f6668ff5e3fe2b3155d161c30327d855d1ad7584337ee0eed3d2d85",
|
||||
"s2cStreamKey": "7d859e27ebf54f5117dc173919f4952ca4a79d449b39ca4cb66dc982ad6df43c",
|
||||
"s2cStreamSalt": "98f157f145f68670eafcc2a1e114ae269d5efe1fbc89d806",
|
||||
"s2cMacKey": "902cce94c7e7335027c3ed5ac695e6ba9ebfef8a2d8dd94bd7bf522b2f78a185",
|
||||
"s2cUdpKey": "fb470d7c6dd2980c070303660e7d11726a3b92fab057b5d6a2f63a75fc1b9453",
|
||||
"object0": "000102",
|
||||
"udp0": "000102030405060708090a0b0c0d0e0f101112131415161752519f6c14b9af07c4ff6e4506bded91385f473d499ae7a1bd77ff90835751",
|
||||
"object1": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445",
|
||||
"udp1": "18191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f27e785c70cb414797285f7ece74d227f7c8773bafdc1fc59c19631825e48b1352adee3f0c8a9a61c1d49c40f6207fde77ccc279982109f22b1b33ce02f71ffe3565d6c5aa656d58caa8aded51d35c6cef5aefd5b8c08b7c892901bfbfad7c503f7ec",
|
||||
"object2": "010000",
|
||||
"udp2": "303132333435363738393a3b3c3d3e3f4041424344454647781578e7e4cdfc68bec534773c724439f04787b1f981d09987320ac7637f21",
|
||||
"tcp": "7076dc0a75456996a85759de0c9e1ddc7f19e4f42f8d21b9c67909f4e106a0388494a18df501d78b8e51bf3affa6cd10bff8307afc5b4c45494a0e89d2d11a823a7257f7d52c0379d3333e33753933630e270d5fa61f11106d80095feff564231280114d47d12d9af30825d86bb1bbf6339c0047f65976ec0c370230fab18a2f7d79ea93d848b069f0a99b42dc6bf2b6ef96f498"
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Independent suite-1 composition oracle. Synthetic secrets ONLY; stdlib + system libsodium.
|
||||
No Kotlin code or output is imported. Regenerate with: python3 tools/concealed-vectors/reference.py
|
||||
"""
|
||||
import ctypes as c
|
||||
import ctypes.util
|
||||
import hashlib
|
||||
import json
|
||||
import struct
|
||||
from pathlib import Path
|
||||
s = c.CDLL(ctypes.util.find_library('sodium'))
|
||||
s.sodium_init()
|
||||
def call(name, n, *args):
|
||||
out = c.create_string_buffer(n)
|
||||
assert getattr(s, name)(out, *args) == 0, name
|
||||
return out.raw
|
||||
|
||||
def h(x): return hashlib.blake2b(x,digest_size=32).digest()
|
||||
def u32(x): return struct.pack('>I',x)
|
||||
def u64(x): return struct.pack('>Q',x)
|
||||
def v(x): return u32(len(x))+x
|
||||
def label(x): return v(x.encode())
|
||||
def kdf(n,k,l,ctx): return hashlib.blake2b(label('kiloparsec/concealed/1')+label(l)+v(ctx),key=k,digest_size=n).digest()
|
||||
def box(m,n,k): return call('crypto_secretbox_easy',len(m)+16,m,c.c_ulonglong(len(m)),n,k)
|
||||
def envelope(k,ctx,m):
|
||||
length=u32(len(m))
|
||||
return b''.join(box(part,kdf(24,k,'flight/'+name+'-iv',ctx),kdf(32,k,'flight/'+name+'-key',ctx)) for name,part in [('header',length),('body',length+m)])
|
||||
def signkey(seed):
|
||||
pk=c.create_string_buffer(32); sk=c.create_string_buffer(64)
|
||||
assert s.crypto_sign_seed_keypair(pk,sk,seed)==0
|
||||
return pk.raw,sk.raw
|
||||
|
||||
def sign(m,sk):
|
||||
out=c.create_string_buffer(64); size=c.c_ulonglong()
|
||||
assert s.crypto_sign_detached(out,c.byref(size),m,c.c_ulonglong(len(m)),sk)==0
|
||||
return out.raw
|
||||
|
||||
def decode(r):
|
||||
p=2**255-19; A=486662; r=int.from_bytes(r,'little')&((1<<254)-1)
|
||||
w=-A*pow((1+2*r*r)%p,-1,p)%p
|
||||
square=pow((w**3+A*w*w+w)%p,(p-1)//2,p) in (0,1)
|
||||
return (w if square else (-w-A)%p).to_bytes(32,'little')
|
||||
|
||||
# Original ChaCha20 implementation: 64-bit counter and 64-bit nonce.
|
||||
def chacha(key,nonce,data):
|
||||
def rot(x,n): return ((x<<n)|(x>>(32-n)))&0xffffffff
|
||||
def quarter(x,a,b,c_,d):
|
||||
x[a]=(x[a]+x[b])&0xffffffff; x[d]=rot(x[d]^x[a],16)
|
||||
x[c_]=(x[c_]+x[d])&0xffffffff; x[b]=rot(x[b]^x[c_],12)
|
||||
x[a]=(x[a]+x[b])&0xffffffff; x[d]=rot(x[d]^x[a],8)
|
||||
x[c_]=(x[c_]+x[d])&0xffffffff; x[b]=rot(x[b]^x[c_],7)
|
||||
out=bytearray()
|
||||
for counter in range((len(data)+63)//64):
|
||||
state=list(struct.unpack('<4I',b'expand 32-byte k'))+list(struct.unpack('<8I',key))+[counter&0xffffffff,counter>>32]+list(struct.unpack('<2I',nonce))
|
||||
x=state[:]
|
||||
for _ in range(10):
|
||||
for q in [(0,4,8,12),(1,5,9,13),(2,6,10,14),(3,7,11,15),(0,5,10,15),(1,6,11,12),(2,7,8,13),(3,4,9,14)]: quarter(x,*q)
|
||||
out.extend(struct.pack('<16I',*((a+b)&0xffffffff for a,b in zip(x,state))))
|
||||
return bytes(a^b for a,b in zip(data,out))
|
||||
|
||||
def main():
|
||||
f={}
|
||||
def put(name,value): f[name]=value.hex(); return value
|
||||
e=put('serverSecret',bytes(range(32)))
|
||||
E=put('serverPublic',call('crypto_scalarmult_base',32,e))
|
||||
cs=put('clientDhSecret',bytes(range(32,64))); C=put('clientDhPublic',call('crypto_scalarmult_base',32,cs))
|
||||
ss=put('serverDhSecret',bytes(range(64,96))); S=put('serverDhPublic',call('crypto_scalarmult_base',32,ss))
|
||||
vs,sks=signkey(put('serverSigningSeed',bytes(range(96,128)))); put('serverIdentity',vs)
|
||||
vc,skc=signkey(put('clientSigningSeed',bytes(range(128,160)))); put('clientIdentity',vc)
|
||||
R=put('representative',bytes(range(160,192))); U=put('heloIv',bytes(range(192,216)))
|
||||
shared=put('bootstrapShared',call('crypto_scalarmult',32,e,decode(R)))
|
||||
context=R+U+E; root=put('bootstrapRoot',kdf(32,shared,'bootstrap',context))
|
||||
bounds=u32(1048576)+struct.pack('>H',0)+u32(0)
|
||||
core=put('heloCore',bytes([1,1])+C+vs+bounds)
|
||||
F1=put('f1',R+U+envelope(root,h(context),v(core)))
|
||||
h1=put('h1',h(label('helo')+v(F1)))
|
||||
I=put('replyIv',bytes(range(24))); replyroot=put('replyRoot',kdf(32,C,'server-reply',h1+E+vs))
|
||||
core=put('serverCore',bytes([1,1])+S+h(label('helo-decrypted')+C)+vs+bounds)
|
||||
sig=put('serverSignature',sign(label('kiloparsec/concealed/1/server-auth')+h1+v(core),sks))
|
||||
F2=put('f2',I+envelope(replyroot,h(label('server-flight')+h1+I),v(core)+sig))
|
||||
h2=put('h2',h(label('handshake')+v(F1)+v(F2)))
|
||||
# Independent crypto_kx formula, not a crypto_kx API call.
|
||||
shared=put('sessionShared',call('crypto_scalarmult',32,cs,S))
|
||||
kx=hashlib.blake2b(shared+C+S,digest_size=64).digest()
|
||||
s2c=put('s2c',kx[:32]); c2s=put('c2s',kx[32:])
|
||||
token=put('token',kdf(32,c2s+s2c,'connection-token',h2))
|
||||
finishc=put('finishedC2s',kdf(32,c2s,'finished/c2s',h2)); finishs=put('finishedS2c',kdf(32,s2c,'finished/s2c',h2))
|
||||
sig=put('clientSignature',sign(label('kiloparsec/concealed/1/client-auth')+token+h2+vc,skc))
|
||||
core=put('ackCore',bytes([3])+h2+vc+sig); A=put('ackIv',bytes(range(24,48)))
|
||||
F3=put('f3',A+envelope(finishc,h(label('ack')+h2+A),v(core)))
|
||||
h3=put('h3',h(label('authenticated-handshake')+h2+v(F3)))
|
||||
core=put('acceptCore',bytes([4])+h3); J=put('acceptIv',bytes(range(48,72)))
|
||||
put('f4',J+envelope(finishs,h(label('accept')+h2+J),v(core)))
|
||||
for name,key in [('c2s',c2s),('s2c',s2c)]:
|
||||
for suffix,label_,n in [('StreamKey','stream',32),('StreamSalt','salt',24),('MacKey','mac',32),('UdpKey','udp',32)]: put(name+suffix,kdf(n,key,'traffic/'+label_+'/'+name,h3))
|
||||
get=lambda name: bytes.fromhex(f[name])
|
||||
streamkey=hashlib.blake2b(b'kiloparsec/concealed/stream-key/v1'+get('c2sStreamSalt'),key=get('c2sStreamKey'),digest_size=32).digest()
|
||||
streamnonce=hashlib.blake2b(b'kiloparsec/concealed/stream-nonce/v1'+get('c2sStreamSalt'),key=get('c2sStreamKey'),digest_size=16).digest()[:8]
|
||||
objects=[bytes([0,1,2]),bytes(range(70)),bytes([1,0,0])]; plain=b''
|
||||
for q,obj in enumerate(objects):
|
||||
put('object'+str(q),obj); body=v(obj); length=u32(len(body))
|
||||
tag=hashlib.blake2b(b'kiloparsec/concealed/record-mac/v1'+u64(q)+length+body,key=get('c2sMacKey'),digest_size=16).digest()
|
||||
plain+=length+body+tag
|
||||
iv=bytes((i+q*24)%256 for i in range(24))
|
||||
put('udp'+str(q),iv+box(u64(q)+body,iv,get('c2sUdpKey')))
|
||||
put('tcp',chacha(streamkey,streamnonce,plain))
|
||||
Path('tools/concealed-vectors/fixtures.json').write_text(json.dumps(f,indent=2)+'\n')
|
||||
kotlin='''@file:OptIn(ExperimentalUnsignedTypes::class)\npackage net.sergeych.kiloparsec.concealed.handshake\n\n// Generated by tools/concealed-vectors/reference.py; synthetic secrets ONLY.\ninternal object IndependentWireFixtures {\n fun bytes(name: String): UByteArray = values.getValue(name).chunked(2).map { it.toUByte(16) }.toUByteArray()\n private val values = mapOf(\n'''+''.join(' "'+k+'" to "'+value+'",\n' for k,value in f.items())+' )\n}\n'
|
||||
Path('src/commonTest/kotlin/net/sergeych/kiloparsec/concealed/handshake/IndependentWireFixtures.kt').write_text(kotlin)
|
||||
print('Generated',len(f),'synthetic fixture fields')
|
||||
if __name__=='__main__': main()
|
||||
Reference in new issue
Block a user