-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathoblivious-transfer.mjs
98 lines (66 loc) · 2.96 KB
/
oblivious-transfer.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { ed25519 } from '@noble/curves/ed25519'
import { deriveKey2 } from './kdf.mjs'
import { decryptAuthenticated, encryptAuthenticated } from './symmetric.mjs'
export function demoObliviousTransfer(choice) {
let privateKeyA = ed25519.utils.randomPrivateKey()
let publicKeyA = ed25519.getPublicKey(privateKeyA)
let privateKeyB = ed25519.utils.randomPrivateKey()
let publicKeyB = ed25519.getPublicKey(privateKeyB)
privateKeyA = ed25519.utils.getExtendedPublicKey(privateKeyA).scalar
privateKeyB = ed25519.utils.getExtendedPublicKey(privateKeyB).scalar
publicKeyA = ed25519.ExtendedPoint.fromHex(publicKeyA)
publicKeyB = ed25519.ExtendedPoint.fromHex(publicKeyB)
const choicePublicKeyB =
(choice == 0) ? publicKeyB : publicKeyA.add(publicKeyB)
// Includes a subgroup check for the given point
// https://eprint.iacr.org/2021/1130
publicKeyA.assertValidity()
choicePublicKeyB.assertValidity()
const keyPointA1 = choicePublicKeyB.multiply(privateKeyA)
const keyPointA2 = choicePublicKeyB.subtract(publicKeyA).multiply(privateKeyA)
const keyPointB = publicKeyA.multiply(privateKeyB)
const keyA1 = deriveKey2(keyPointA1.toRawBytes())
const keyA2 = deriveKey2(keyPointA2.toRawBytes())
const keyB = deriveKey2(keyPointB.toRawBytes())
const messages = [
"a",
"b"
]
const encryptedPackages = [
encryptAuthenticated(keyA1, messages[0]),
encryptAuthenticated(keyA2, messages[1])
]
const plaintext = decryptAuthenticated(keyB, encryptedPackages[choice])
console.log("OT choice checks:", plaintext == messages[choice])
try {
const plaintext = decryptAuthenticated(keyB, encryptedPackages[1 - choice])
console.log("OT non-choice checks:", plaintext == messages[1 - choice])
}
catch(error) {
console.log("OT non-choice generates authentication error")
}
}
export function getReceiverPublicKeyOT(publicKeyA, publicKeyB, choice) {
publicKeyA = ed25519.ExtendedPoint.fromHex(publicKeyA)
publicKeyB = ed25519.ExtendedPoint.fromHex(publicKeyB)
const choicePublicKeyB =
(choice == 0) ? publicKeyB : publicKeyA.add(publicKeyB)
return choicePublicKeyB.toRawBytes()
}
export function getSenderSharedSecretsOT(choicePublicKeyB, publicKeyA, privateKeyA) {
choicePublicKeyB = ed25519.ExtendedPoint.fromHex(choicePublicKeyB)
publicKeyA = ed25519.ExtendedPoint.fromHex(publicKeyA)
privateKeyA = ed25519.utils.getExtendedPublicKey(privateKeyA).scalar
const keyPointA1 = choicePublicKeyB.multiply(privateKeyA)
const keyPointA2 = choicePublicKeyB.subtract(publicKeyA).multiply(privateKeyA)
const keyA1 = deriveKey2(keyPointA1.toRawBytes())
const keyA2 = deriveKey2(keyPointA2.toRawBytes())
return { keySender1: keyA1, keySender2: keyA2 }
}
export function getReceiverSharedSecretOT(publicKeyA, privateKeyB) {
publicKeyA = ed25519.ExtendedPoint.fromHex(publicKeyA)
privateKeyB = ed25519.utils.getExtendedPublicKey(privateKeyB).scalar
const keyPointB = publicKeyA.multiply(privateKeyB)
const keyB = deriveKey2(keyPointB.toRawBytes())
return { keyReceiver: keyB }
}