|
|
|
(function(return_she) {
|
|
|
|
if (typeof exports === 'object') {
|
|
|
|
module.exports = return_she()
|
|
|
|
} else {
|
|
|
|
window.she = return_she()
|
|
|
|
}
|
|
|
|
})(function() {
|
|
|
|
const crypto = window.crypto || window.msCrypto
|
|
|
|
|
|
|
|
const MCLBN_CURVE_FP254BNB = 0
|
|
|
|
const MCLBN_CURVE_FP382_1 = 1
|
|
|
|
const MCLBN_CURVE_FP382_2 = 2
|
|
|
|
|
|
|
|
const MCLBN_FP_UNIT_SIZE = 4
|
|
|
|
|
|
|
|
const MCLBN_FP_SIZE = MCLBN_FP_UNIT_SIZE * 8
|
|
|
|
const MCLBN_G1_SIZE = MCLBN_FP_SIZE * 3
|
|
|
|
const MCLBN_G2_SIZE = MCLBN_FP_SIZE * 6
|
|
|
|
const MCLBN_GT_SIZE = MCLBN_FP_SIZE * 12
|
|
|
|
|
|
|
|
const SHE_SECRETKEY_SIZE = MCLBN_FP_SIZE * 2
|
|
|
|
const SHE_PUBLICKEY_SIZE = MCLBN_G1_SIZE + MCLBN_G2_SIZE
|
|
|
|
const SHE_CIPHERTEXT_G1_SIZE = MCLBN_G1_SIZE * 2
|
|
|
|
const SHE_CIPHERTEXT_G2_SIZE = MCLBN_G2_SIZE * 2
|
|
|
|
const SHE_CIPHERTEXT_GT_SIZE = MCLBN_GT_SIZE * 4
|
|
|
|
|
|
|
|
let mod = {}
|
|
|
|
let capi = {}
|
|
|
|
let self = {}
|
|
|
|
self.mod = mod
|
|
|
|
self.capi = capi
|
|
|
|
|
|
|
|
const setupWasm = function(fileName, nameSpace, setupFct) {
|
|
|
|
console.log('setupWasm ' + fileName)
|
|
|
|
fetch(fileName)
|
|
|
|
.then(response => response.arrayBuffer())
|
|
|
|
.then(buffer => new Uint8Array(buffer))
|
|
|
|
.then(binary => {
|
|
|
|
mod['wasmBinary'] = binary
|
|
|
|
mod['onRuntimeInitialized'] = function() {
|
|
|
|
setupFct(mod, nameSpace)
|
|
|
|
console.log('setupWasm end')
|
|
|
|
}
|
|
|
|
Module(mod)
|
|
|
|
})
|
|
|
|
return mod
|
|
|
|
}
|
|
|
|
const ptrToStr = function(pos, n) {
|
|
|
|
let s = ''
|
|
|
|
for (let i = 0; i < n; i++) {
|
|
|
|
s += String.fromCharCode(mod.HEAP8[pos + i])
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
const Uint8ArrayToMem = function(pos, buf) {
|
|
|
|
for (let i = 0; i < buf.length; i++) {
|
|
|
|
mod.HEAP8[pos + i] = buf[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const AsciiStrToMem = function(pos, s) {
|
|
|
|
for (let i = 0; i < s.length; i++) {
|
|
|
|
mod.HEAP8[pos + i] = s.charCodeAt(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const copyToUint32Array = function(a, pos) {
|
|
|
|
for (let i = 0; i < a.length; i++) {
|
|
|
|
a[i] = mod.HEAP32[pos / 4 + i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const copyFromUint32Array = function(pos, a) {
|
|
|
|
for (let i = 0; i < a.length; i++) {
|
|
|
|
mod.HEAP32[pos / 4 + i] = a[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.toHex = function(a, start, n) {
|
|
|
|
let s = ''
|
|
|
|
for (let i = 0; i < n; i++) {
|
|
|
|
s += ('0' + a[start + i].toString(16)).slice(-2)
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
// Uint8Array to hex string
|
|
|
|
self.toHexStr = function(a) {
|
|
|
|
return self.toHex(a, 0, a.length)
|
|
|
|
}
|
|
|
|
// hex string to Uint8Array
|
|
|
|
self.fromHexStr = function(s) {
|
|
|
|
let n = (s.length + 1) / 2
|
|
|
|
let a = new Uint8Array(n)
|
|
|
|
for (let i = 0; i < s.length / 2; i++) {
|
|
|
|
a[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16)
|
|
|
|
}
|
|
|
|
if ((s.length & 1) != 0) {
|
|
|
|
a[n - 1] = parseInt(s[s.length - 1] + '0', 16)
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
const wrap_outputString = function(func, doesReturnString = true) {
|
|
|
|
return function(x, ioMode = 0) {
|
|
|
|
let maxBufSize = 2048
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let pos = mod.Runtime.stackAlloc(maxBufSize)
|
|
|
|
let n = func(pos, maxBufSize, x, ioMode)
|
|
|
|
if (n < 0) {
|
|
|
|
throw('err gen_str:' + x)
|
|
|
|
}
|
|
|
|
if (doesReturnString) {
|
|
|
|
let s = ptrToStr(pos, n)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return s
|
|
|
|
} else {
|
|
|
|
let a = new Uint8Array(n)
|
|
|
|
for (let i = 0; i < n; i++) {
|
|
|
|
a[i] = mod.HEAP8[pos + i]
|
|
|
|
}
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const wrap_outputArray = function(func) {
|
|
|
|
return wrap_outputString(func, false)
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
argNum : n
|
|
|
|
func(x0, ..., x_(n-1), buf, ioMode)
|
|
|
|
=> func(x0, ..., x_(n-1), pos, buf.length, ioMode)
|
|
|
|
*/
|
|
|
|
const wrap_input = function(func, argNum, returnValue = false) {
|
|
|
|
return function() {
|
|
|
|
const args = [...arguments]
|
|
|
|
let buf = args[argNum]
|
|
|
|
let ioMode = args[argNum + 1] // may undefined
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let pos = mod.Runtime.stackAlloc(buf.length)
|
|
|
|
if (typeof(buf) == "string") {
|
|
|
|
AsciiStrToMem(pos, buf)
|
|
|
|
} else {
|
|
|
|
Uint8ArrayToMem(pos, buf)
|
|
|
|
}
|
|
|
|
let r = func(...args.slice(0, argNum), pos, buf.length, ioMode)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (returnValue) return r
|
|
|
|
if (r) throw('err wrap_input0 ' + buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const wrap_input0 = function(func, returnValue = false) {
|
|
|
|
return function(buf, ioMode = 0) {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let pos = mod.Runtime.stackAlloc(buf.length)
|
|
|
|
if (typeof(buf) == "string") {
|
|
|
|
AsciiStrToMem(pos, buf)
|
|
|
|
} else {
|
|
|
|
Uint8ArrayToMem(pos, buf)
|
|
|
|
}
|
|
|
|
let r = func(pos, buf.length, ioMode)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (returnValue) return r
|
|
|
|
if (r) throw('err wrap_input0 ' + buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const wrap_input1 = function(func, returnValue = false) {
|
|
|
|
return function(x1, buf, ioMode = 0) {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let pos = mod.Runtime.stackAlloc(buf.length)
|
|
|
|
if (typeof(buf) == "string") {
|
|
|
|
AsciiStrToMem(pos, buf)
|
|
|
|
} else {
|
|
|
|
Uint8ArrayToMem(pos, buf)
|
|
|
|
}
|
|
|
|
let r = func(x1, pos, buf.length, ioMode)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (returnValue) return r
|
|
|
|
if (r) throw('err wrap_input1 ' + buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const wrap_input2 = function(func, returnValue = false) {
|
|
|
|
return function(x1, x2, buf, ioMode = 0) {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let pos = mod.Runtime.stackAlloc(buf.length)
|
|
|
|
if (typeof(buf) == "string") {
|
|
|
|
AsciiStrToMem(pos, buf)
|
|
|
|
} else {
|
|
|
|
Uint8ArrayToMem(pos, buf)
|
|
|
|
}
|
|
|
|
let r = func(x1, x2, pos, buf.length, ioMode)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (returnValue) return r
|
|
|
|
if (r) throw('err wrap_input2 ' + buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const callSetter = function(func, a, p1, p2) {
|
|
|
|
let pos = mod._malloc(a.length * 4)
|
|
|
|
func(pos, p1, p2) // p1, p2 may be undefined
|
|
|
|
copyToUint32Array(a, pos)
|
|
|
|
mod._free(pos)
|
|
|
|
}
|
|
|
|
const callGetter = function(func, a, p1, p2) {
|
|
|
|
let pos = mod._malloc(a.length * 4)
|
|
|
|
mod.HEAP32.set(a, pos / 4)
|
|
|
|
let s = func(pos, p1, p2)
|
|
|
|
mod._free(pos)
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
const callModifier = function(func, a, p1, p2) {
|
|
|
|
let pos = mod._malloc(a.length * 4)
|
|
|
|
mod.HEAP32.set(a, pos / 4)
|
|
|
|
func(pos, p1, p2) // p1, p2 may be undefined
|
|
|
|
copyToUint32Array(a, pos)
|
|
|
|
mod._free(pos)
|
|
|
|
}
|
|
|
|
const wrap_dec = function(func) {
|
|
|
|
return function(sec, c) {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let pos = mod.Runtime.stackAlloc(8)
|
|
|
|
let r = func(pos, sec, c)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (r != 0) throw('sheDec')
|
|
|
|
let v = mod.HEAP32[pos / 4]
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const callEnc = function(func, cstr, pub, m) {
|
|
|
|
let c = new cstr()
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let cPos = mod.Runtime.stackAlloc(c.a_.length * 4)
|
|
|
|
let pubPos = mod.Runtime.stackAlloc(pub.length * 4)
|
|
|
|
copyFromUint32Array(pubPos, pub);
|
|
|
|
func(cPos, pubPos, m)
|
|
|
|
copyToUint32Array(c.a_, cPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
// return func(x, y)
|
|
|
|
const callAddSub = function(func, cstr, x, y) {
|
|
|
|
let z = new cstr()
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let xPos = mod.Runtime.stackAlloc(x.length * 4)
|
|
|
|
let yPos = mod.Runtime.stackAlloc(y.length * 4)
|
|
|
|
let zPos = mod.Runtime.stackAlloc(z.a_.length * 4)
|
|
|
|
copyFromUint32Array(xPos, x);
|
|
|
|
copyFromUint32Array(yPos, y);
|
|
|
|
func(zPos, xPos, yPos)
|
|
|
|
copyToUint32Array(z.a_, zPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return z
|
|
|
|
}
|
|
|
|
// return func(x, y)
|
|
|
|
const callMulInt = function(func, cstr, x, y) {
|
|
|
|
let z = new cstr()
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let xPos = mod.Runtime.stackAlloc(x.length * 4)
|
|
|
|
let zPos = mod.Runtime.stackAlloc(z.a_.length * 4)
|
|
|
|
copyFromUint32Array(xPos, x);
|
|
|
|
func(zPos, xPos, y)
|
|
|
|
copyToUint32Array(z.a_, zPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return z
|
|
|
|
}
|
|
|
|
// return func(c)
|
|
|
|
const callDec = function(func, sec, c) {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let secPos = mod.Runtime.stackAlloc(sec.length * 4)
|
|
|
|
let cPos = mod.Runtime.stackAlloc(c.length * 4)
|
|
|
|
copyFromUint32Array(secPos, sec);
|
|
|
|
copyFromUint32Array(cPos, c);
|
|
|
|
let r = func(secPos, cPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
// reRand(c)
|
|
|
|
const callReRand = function(func, c, pub) {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let cPos = mod.Runtime.stackAlloc(c.length * 4)
|
|
|
|
let pubPos = mod.Runtime.stackAlloc(pub.length * 4)
|
|
|
|
copyFromUint32Array(cPos, c);
|
|
|
|
copyFromUint32Array(pubPos, pub);
|
|
|
|
let r = func(cPos, pubPos)
|
|
|
|
copyToUint32Array(c, cPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (r) throw('callReRand err')
|
|
|
|
}
|
|
|
|
// convertFrom
|
|
|
|
const callConvertFrom = function(func, pub, c) {
|
|
|
|
let ct = new self.CipherTextGT()
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let ctPos = mod.Runtime.stackAlloc(ct.a_.length * 4)
|
|
|
|
let pubPos = mod.Runtime.stackAlloc(pub.length * 4)
|
|
|
|
let cPos = mod.Runtime.stackAlloc(c.length * 4)
|
|
|
|
copyFromUint32Array(pubPos, pub);
|
|
|
|
copyFromUint32Array(cPos, c);
|
|
|
|
let r = func(ctPos, pubPos, cPos)
|
|
|
|
copyToUint32Array(ct.a_, ctPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
if (r) throw('callConvertFrom err')
|
|
|
|
return ct
|
|
|
|
}
|
|
|
|
const define_extra_functions = function(mod) {
|
|
|
|
capi.she_free = function(p) {
|
|
|
|
mod._free(p)
|
|
|
|
}
|
|
|
|
capi.sheSecretKey_malloc = function() {
|
|
|
|
return mod._malloc(SHE_SECRETKEY_SIZE)
|
|
|
|
}
|
|
|
|
capi.shePublicKey_malloc = function() {
|
|
|
|
return mod._malloc(SHE_PUBLICKEY_SIZE)
|
|
|
|
}
|
|
|
|
capi.sheCipherTextG2_malloc = function() {
|
|
|
|
return mod._malloc(SHE_CIPHERTEXT_G2_SIZE)
|
|
|
|
}
|
|
|
|
capi.sheCipherTextGT_malloc = function() {
|
|
|
|
return mod._malloc(SHE_CIPHERTEXT_GT_SIZE)
|
|
|
|
}
|
|
|
|
capi.sheCipherTextG1_malloc = function() {
|
|
|
|
return mod._malloc(SHE_CIPHERTEXT_G1_SIZE)
|
|
|
|
}
|
|
|
|
capi.sheSecretKeySerialize = wrap_outputArray(capi._sheSecretKeySerialize)
|
|
|
|
capi.sheSecretKeyDeserialize = wrap_input(capi._sheSecretKeyDeserialize, 1)
|
|
|
|
capi.shePublicKeySerialize = wrap_outputArray(capi._shePublicKeySerialize)
|
|
|
|
capi.shePublicKeyDeserialize = wrap_input(capi._shePublicKeyDeserialize, 1)
|
|
|
|
capi.sheCipherTextG1Serialize = wrap_outputArray(capi._sheCipherTextG1Serialize)
|
|
|
|
capi.sheCipherTextG1Deserialize = wrap_input(capi._sheCipherTextG1Deserialize, 1)
|
|
|
|
capi.sheDecG1 = wrap_dec(capi._sheDecG1)
|
|
|
|
capi.sheCipherTextG2Serialize = wrap_outputArray(capi._sheCipherTextG2Serialize)
|
|
|
|
capi.sheCipherTextG2Deserialize = wrap_input(capi._sheCipherTextG2Deserialize, 1)
|
|
|
|
capi.sheDecG2 = wrap_dec(capi._sheDecG2)
|
|
|
|
capi.sheCipherTextGTSerialize = wrap_outputArray(capi._sheCipherTextGTSerialize)
|
|
|
|
capi.sheCipherTextGTDeserialize = wrap_input(capi._sheCipherTextGTDeserialize, 1)
|
|
|
|
capi.sheDecGT = wrap_dec(capi._sheDecGT)
|
|
|
|
|
|
|
|
capi.sheInit = function(curveType = MCLBN_CURVE_FP254BNB) {
|
|
|
|
let r = capi._sheInit(curveType, MCLBN_FP_UNIT_SIZE)
|
|
|
|
console.log('sheInit ' + r)
|
|
|
|
if (r) throw('sheInit')
|
|
|
|
}
|
|
|
|
class Common {
|
|
|
|
constructor(size) {
|
|
|
|
this.a_ = new Uint32Array(size / 4)
|
|
|
|
}
|
|
|
|
fromHexStr(s) {
|
|
|
|
this.deserialize(self.fromHexStr(s))
|
|
|
|
}
|
|
|
|
toHexStr() {
|
|
|
|
return self.toHexStr(this.serialize())
|
|
|
|
}
|
|
|
|
dump(msg = '') {
|
|
|
|
console.log(msg + this.toHexStr())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.SecretKey = class extends Common {
|
|
|
|
constructor() {
|
|
|
|
super(SHE_SECRETKEY_SIZE)
|
|
|
|
}
|
|
|
|
serialize() {
|
|
|
|
return callGetter(capi.sheSecretKeySerialize, this.a_)
|
|
|
|
}
|
|
|
|
deserialize(s) {
|
|
|
|
callSetter(capi.sheSecretKeyDeserialize, this.a_, s)
|
|
|
|
}
|
|
|
|
setByCSPRNG() {
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let secPos = mod.Runtime.stackAlloc(this.a_.length * 4)
|
|
|
|
capi.sheSecretKeySetByCSPRNG(secPos)
|
|
|
|
copyToUint32Array(this.a_, secPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
}
|
|
|
|
getPublicKey() {
|
|
|
|
let pub = new self.PublicKey()
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let secPos = mod.Runtime.stackAlloc(this.a_.length * 4)
|
|
|
|
let pubPos = mod.Runtime.stackAlloc(pub.a_.length * 4)
|
|
|
|
copyFromUint32Array(secPos, this.a_)
|
|
|
|
capi.sheGetPublicKey(pubPos, secPos)
|
|
|
|
copyToUint32Array(pub.a_, pubPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return pub
|
|
|
|
}
|
|
|
|
dec(c) {
|
|
|
|
let dec = null
|
|
|
|
if (self.CipherTextG1.prototype.isPrototypeOf(c)) {
|
|
|
|
dec = capi.sheDecG1
|
|
|
|
} else if (self.CipherTextG2.prototype.isPrototypeOf(c)) {
|
|
|
|
dec = capi.sheDecG2
|
|
|
|
} else if (self.CipherTextGT.prototype.isPrototypeOf(c)) {
|
|
|
|
dec = capi.sheDecGT
|
|
|
|
} else {
|
|
|
|
throw('self.SecretKey.dec:not supported')
|
|
|
|
}
|
|
|
|
return callDec(dec, this.a_, c.a_)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.getSecretKeyFromHexStr = function(s) {
|
|
|
|
r = new self.SecretKey()
|
|
|
|
r.fromHexStr(s)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
self.PublicKey = class extends Common {
|
|
|
|
constructor() {
|
|
|
|
super(SHE_PUBLICKEY_SIZE)
|
|
|
|
}
|
|
|
|
serialize() {
|
|
|
|
return callGetter(capi.shePublicKeySerialize, this.a_)
|
|
|
|
}
|
|
|
|
deserialize(s) {
|
|
|
|
callSetter(capi.shePublicKeyDeserialize, this.a_, s)
|
|
|
|
}
|
|
|
|
encG1(m) {
|
|
|
|
return callEnc(capi.sheEnc32G1, self.CipherTextG1, this.a_, m)
|
|
|
|
}
|
|
|
|
encG2(m) {
|
|
|
|
return callEnc(capi.sheEnc32G2, self.CipherTextG2, this.a_, m)
|
|
|
|
}
|
|
|
|
encGT(m) {
|
|
|
|
return callEnc(capi.sheEnc32GT, self.CipherTextGT, this.a_, m)
|
|
|
|
}
|
|
|
|
reRand(c) {
|
|
|
|
let reRand = null
|
|
|
|
if (self.CipherTextG1.prototype.isPrototypeOf(c)) {
|
|
|
|
reRand = capi.sheReRandG1
|
|
|
|
} else if (self.CipherTextG2.prototype.isPrototypeOf(c)) {
|
|
|
|
reRand = capi.sheReRandG2
|
|
|
|
} else if (self.CipherTextGT.prototype.isPrototypeOf(c)) {
|
|
|
|
reRand = capi.sheReRandGT
|
|
|
|
} else {
|
|
|
|
throw('self.PublicKey.reRand:not supported')
|
|
|
|
}
|
|
|
|
return callReRand(reRand, c.a_, this.a_)
|
|
|
|
}
|
|
|
|
convertToCipherTextGT(c) {
|
|
|
|
let convertFrom = null
|
|
|
|
if (self.CipherTextG1.prototype.isPrototypeOf(c)) {
|
|
|
|
convertFrom = capi.sheConvertFromG1
|
|
|
|
} else if (self.CipherTextG2.prototype.isPrototypeOf(c)) {
|
|
|
|
convertFrom = capi.sheConvertFromG2
|
|
|
|
} else {
|
|
|
|
throw('self.PublicKey.convertToCipherTextGT:not supported')
|
|
|
|
}
|
|
|
|
return callConvertFrom(convertFrom, this.a_, c.a_)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.getPublicKeyFromHexStr = function(s) {
|
|
|
|
r = new self.PublicKey()
|
|
|
|
r.fromHexStr(s)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
self.CipherTextG1 = class extends Common {
|
|
|
|
constructor() {
|
|
|
|
super(SHE_CIPHERTEXT_G1_SIZE)
|
|
|
|
}
|
|
|
|
serialize() {
|
|
|
|
return callGetter(capi.sheCipherTextG1Serialize, this.a_)
|
|
|
|
}
|
|
|
|
deserialize(s) {
|
|
|
|
callSetter(capi.sheCipherTextG1Deserialize, this.a_, s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.getCipherTextG1FromHexStr = function(s) {
|
|
|
|
r = new self.CipherTextG1()
|
|
|
|
r.fromHexStr(s)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
self.CipherTextG2 = class extends Common {
|
|
|
|
constructor() {
|
|
|
|
super(SHE_CIPHERTEXT_G2_SIZE)
|
|
|
|
}
|
|
|
|
serialize() {
|
|
|
|
return callGetter(capi.sheCipherTextG2Serialize, this.a_)
|
|
|
|
}
|
|
|
|
deserialize(s) {
|
|
|
|
callSetter(capi.sheCipherTextG2Deserialize, this.a_, s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.getCipherTextG2FromHexStr = function(s) {
|
|
|
|
r = new self.CipherTextG2()
|
|
|
|
r.fromHexStr(s)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
self.CipherTextGT = class extends Common {
|
|
|
|
constructor() {
|
|
|
|
super(SHE_CIPHERTEXT_GT_SIZE)
|
|
|
|
}
|
|
|
|
serialize() {
|
|
|
|
return callGetter(capi.sheCipherTextGTSerialize, this.a_)
|
|
|
|
}
|
|
|
|
deserialize(s) {
|
|
|
|
callSetter(capi.sheCipherTextGTDeserialize, this.a_, s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.getCipherTextGTFromHexStr = function(s) {
|
|
|
|
r = new self.CipherTextGT()
|
|
|
|
r.fromHexStr(s)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
// return x + y
|
|
|
|
self.add = function(x, y) {
|
|
|
|
if (x.a_.length != y.a_.length) throw('self.add:bad type')
|
|
|
|
let add = null
|
|
|
|
let cstr = null
|
|
|
|
if (self.CipherTextG1.prototype.isPrototypeOf(x)) {
|
|
|
|
add = capi.sheAddG1
|
|
|
|
cstr = self.CipherTextG1
|
|
|
|
} else if (self.CipherTextG2.prototype.isPrototypeOf(x)) {
|
|
|
|
add = capi.sheAddG2
|
|
|
|
cstr = self.CipherTextG2
|
|
|
|
} else if (self.CipherTextGT.prototype.isPrototypeOf(x)) {
|
|
|
|
add = capi.sheAddGT
|
|
|
|
cstr = self.CipherTextGT
|
|
|
|
} else {
|
|
|
|
throw('self.add:not supported')
|
|
|
|
}
|
|
|
|
return callAddSub(add, cstr, x.a_, y.a_)
|
|
|
|
}
|
|
|
|
// return x - y
|
|
|
|
self.sub = function(x, y) {
|
|
|
|
if (x.a_.length != y.a_.length) throw('self.sub:bad type')
|
|
|
|
let sub = null
|
|
|
|
let cstr = null
|
|
|
|
if (self.CipherTextG1.prototype.isPrototypeOf(x)) {
|
|
|
|
sub = capi.sheSubG1
|
|
|
|
cstr = self.CipherTextG1
|
|
|
|
} else if (self.CipherTextG2.prototype.isPrototypeOf(x)) {
|
|
|
|
sub = capi.sheSubG2
|
|
|
|
cstr = self.CipherTextG2
|
|
|
|
} else if (self.CipherTextGT.prototype.isPrototypeOf(x)) {
|
|
|
|
sub = capi.sheSubGT
|
|
|
|
cstr = self.CipherTextGT
|
|
|
|
} else {
|
|
|
|
throw('self.sub:not supported')
|
|
|
|
}
|
|
|
|
return callAddSub(sub, cstr, x.a_, y.a_)
|
|
|
|
}
|
|
|
|
// return x * (int)y
|
|
|
|
self.mulInt = function(x, y) {
|
|
|
|
let mulInt = null
|
|
|
|
let cstr = null
|
|
|
|
if (self.CipherTextG1.prototype.isPrototypeOf(x)) {
|
|
|
|
mulInt = capi.sheMul32G1
|
|
|
|
cstr = self.CipherTextG1
|
|
|
|
} else if (self.CipherTextG2.prototype.isPrototypeOf(x)) {
|
|
|
|
mulInt = capi.sheMul32G2
|
|
|
|
cstr = self.CipherTextG2
|
|
|
|
} else if (self.CipherTextGT.prototype.isPrototypeOf(x)) {
|
|
|
|
mulInt = capi.sheMul32GT
|
|
|
|
cstr = self.CipherTextGT
|
|
|
|
} else {
|
|
|
|
throw('self.mulInt:not supported')
|
|
|
|
}
|
|
|
|
return callMulInt(mulInt, cstr, x.a_, y)
|
|
|
|
}
|
|
|
|
// return (G1)x * (G2)y
|
|
|
|
self.mul = function(x, y) {
|
|
|
|
if (!self.CipherTextG1.prototype.isPrototypeOf(x)
|
|
|
|
|| !self.CipherTextG2.prototype.isPrototypeOf(y)) throw('self.mul:bad type')
|
|
|
|
let z = new self.CipherTextGT()
|
|
|
|
let stack = mod.Runtime.stackSave()
|
|
|
|
let xPos = mod.Runtime.stackAlloc(x.a_.length * 4)
|
|
|
|
let yPos = mod.Runtime.stackAlloc(y.a_.length * 4)
|
|
|
|
let zPos = mod.Runtime.stackAlloc(z.a_.length * 4)
|
|
|
|
copyFromUint32Array(xPos, x.a_)
|
|
|
|
copyFromUint32Array(yPos, y.a_)
|
|
|
|
capi.sheMul(zPos, xPos, yPos)
|
|
|
|
copyToUint32Array(z.a_, zPos)
|
|
|
|
mod.Runtime.stackRestore(stack)
|
|
|
|
return z
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.init = function(range = 1024, tryNum = 1024, callback = null) {
|
|
|
|
setupWasm('mclshe.wasm', null, function(_mod, ns) {
|
|
|
|
mod = _mod
|
|
|
|
fetch('exported-she.json')
|
|
|
|
.then(response => response.json())
|
|
|
|
.then(json => {
|
|
|
|
mod.json = json
|
|
|
|
json.forEach(func => {
|
|
|
|
capi[func.exportName] = mod.cwrap(func.name, func.returns, func.args)
|
|
|
|
})
|
|
|
|
define_extra_functions(mod)
|
|
|
|
capi.sheInit()
|
|
|
|
console.log('initializing sheSetRangeForDLP')
|
|
|
|
let r = capi.sheSetRangeForDLP(range, tryNum)
|
|
|
|
console.log('finished ' + r)
|
|
|
|
if (callback) callback()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return self
|
|
|
|
})
|