[js] she.js supports Node.js and browser

dev
MITSUNARI Shigeo 7 years ago
parent 03925e780a
commit 18ac8a55d2
  1. 2
      Makefile
  2. 8
      docs/demo/she-demo.js
  3. 20
      docs/demo/she-demo2.js
  4. 236
      docs/demo/she.js

@ -222,7 +222,7 @@ docs/demo/mclshe.js: src/fp.cpp src/she_c256.cpp $(SHE_TXT) $(EXPORTED_SHE_JS) s
emcc -o $@ src/fp.cpp src/she_c256.cpp -I./include -I./src -I../cybozulib/include -s WASM=1 -s "MODULARIZE=1" -s "EXPORTED_FUNCTIONS=[$(EXPORTED_SHE)]" -O3 -DNDEBUG -DMCLBN_FP_UNIT_SIZE=4 -DMCL_MAX_BIT_SIZE=256 -s DISABLE_EXCEPTION_CATCHING=0 -s NO_EXIT_RUNTIME=1 -DMCLSHE_WIN_SIZE=8
../she-wasm/she.js: src/fp.cpp src/she_c256.cpp src/she_c_impl.hpp include/mcl/she.hpp include/mcl/she.h include/mcl/bn.h
cd ../she-wasm && emcc -O3 -DNDEBUG -DMCLBN_FP_UNIT_SIZE=4 -DMCL_MAX_BIT_SIZE=256 -s WASM=1 -s DISABLE_EXCEPTION_CATCHING=0 -s NO_EXIT_RUNTIME=1 -DMCLSHE_WIN_SIZE=8 -o she.js ../mcl/src/fp.cpp ../mcl/src/she_c256.cpp -I../mcl/include -I../mcl/src -I../cybozulib/include
cd ../she-wasm && emcc -O3 -DNDEBUG -DMCLBN_FP_UNIT_SIZE=4 -DMCL_MAX_BIT_SIZE=256 -s WASM=1 -s DISABLE_EXCEPTION_CATCHING=0 -s NO_EXIT_RUNTIME=1 -DMCLSHE_WIN_SIZE=8 -o she.js ../mcl/src/fp.cpp ../mcl/src/she_c256.cpp -I../mcl/include -I../mcl/src -I../cybozulib/include && cp ../mcl/docs/demo/she.js index.js
demo:
$(MAKE) docs/demo/mclshe.js

@ -4,10 +4,10 @@ function getText(name) { return document.getElementsByName(name)[0].innerText }
function setText(name, val) { document.getElementsByName(name)[0].innerText = val }
(function() {
const range = 2048
const tryNum = 100
she.init(range, tryNum, function() { setText('status', 'ok')})
}())
she.init(function() {
setText('status', 'ok')
})
})()
function bench(label, count, func) {
let start = Date.now()

@ -45,18 +45,14 @@ function strip(s) {
}
(function() {
const range = 2048
const tryNum = 100
she.init(range, tryNum, function() {
setText('status', 'ok')
sec = new she.SecretKey()
sec.setByCSPRNG()
setText('sec', sec.toHexStr())
pub = sec.getPublicKey()
setText('pub', pub.toHexStr())
})
}())
she.init(function() {
setText('status', 'ok')
sec = new she.SecretKey()
sec.setByCSPRNG()
setText('sec', sec.toHexStr())
pub = sec.getPublicKey()
setText('pub', pub.toHexStr())
})
function append() {
let v = getValue('append')

@ -1,11 +1,11 @@
(function(return_she) {
(function(generator) {
if (typeof exports === 'object') {
module.exports = return_she()
generator(exports, true)
} else {
window.she = return_she()
let exports = {}
window.she = generator(exports, false)
}
})(function() {
const crypto = window.crypto || window.msCrypto
})(function(exports, isNodeJs) {
const MCLBN_CURVE_FP254BNB = 0
const MCLBN_CURVE_FP382_1 = 1
@ -26,24 +26,65 @@
let mod = {}
let capi = {}
let self = {}
self.mod = mod
self.capi = capi
let g_callback = null
let g_range = 1024
let g_tryNum = 1024
exports.mod = mod
exports.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['onRuntimeInitialized'] = function() {
setupFct(mod, nameSpace)
console.log('setupWasm end')
}
Module(mod)
if (isNodeJs) {
mod = require('./she.js')
exports.init = function(callback) {
console.log('onModuleInit')
g_callback = callback
}
mod.onRuntimeInitialized = function () {
const fs = require('fs')
const json = fs.readFileSync('./exported-she.json')
exportedFuncs = JSON.parse(json)
exportedFuncs.forEach(func => {
capi[func.exportName] = mod.cwrap(func.name, func.returns, func.args)
})
return mod
define_extra_functions(mod)
capi.sheInit()
console.log('initializing sheSetRangeForDLP')
let range = 1024
let tryNum = 512
let r = capi.sheSetRangeForDLP(range, tryNum)
console.log('finished ' + r)
if (g_callback) g_callback()
}
} else {
exports.init = function(callback = null, range = 1024, tryNum = 1024) {
g_callback = callback
g_range = range
g_tryNum = tryNum
fetch('mclshe.wasm')
.then(response => response.arrayBuffer())
.then(buffer => new Uint8Array(buffer))
.then(binary => {
Module(mod)
})
}
mod.onRuntimeInitialized = function() {
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(g_range, g_tryNum)
console.log('finished ' + r)
if (g_callback) g_callback()
})
}
}
const ptrToStr = function(pos, n) {
let s = ''
for (let i = 0; i < n; i++) {
@ -72,7 +113,7 @@
mod.HEAP32[pos / 4 + i] = a[i]
}
}
self.toHex = function(a, start, n) {
exports.toHex = function(a, start, n) {
let s = ''
for (let i = 0; i < n; i++) {
s += ('0' + a[start + i].toString(16)).slice(-2)
@ -80,11 +121,11 @@
return s
}
// Uint8Array to hex string
self.toHexStr = function(a) {
return self.toHex(a, 0, a.length)
exports.toHexStr = function(a) {
return exports.toHex(a, 0, a.length)
}
// hex string to Uint8Array
self.fromHexStr = function(s) {
exports.fromHexStr = function(s) {
if (s.length & 1) throw('fromHexStr:length must be even ' + s.length)
let n = s.length / 2
let a = new Uint8Array(n)
@ -229,7 +270,7 @@
}
// convertFrom
const callConvertFrom = function(func, pub, c) {
let ct = new self.CipherTextGT()
let ct = new exports.CipherTextGT()
let stack = mod.Runtime.stackSave()
let ctPos = mod.Runtime.stackAlloc(ct.a_.length * 4)
let pubPos = mod.Runtime.stackAlloc(pub.length * 4)
@ -285,16 +326,16 @@
this.a_ = new Uint32Array(size / 4)
}
fromHexStr(s) {
this.deserialize(self.fromHexStr(s))
this.deserialize(exports.fromHexStr(s))
}
toHexStr() {
return self.toHexStr(this.serialize())
return exports.toHexStr(this.serialize())
}
dump(msg = '') {
console.log(msg + this.toHexStr())
}
}
self.SecretKey = class extends Common {
exports.SecretKey = class extends Common {
constructor() {
super(SHE_SECRETKEY_SIZE)
}
@ -312,7 +353,7 @@
mod.Runtime.stackRestore(stack)
}
getPublicKey() {
let pub = new self.PublicKey()
let pub = new exports.PublicKey()
let stack = mod.Runtime.stackSave()
let secPos = mod.Runtime.stackAlloc(this.a_.length * 4)
let pubPos = mod.Runtime.stackAlloc(pub.a_.length * 4)
@ -324,25 +365,25 @@
}
dec(c) {
let dec = null
if (self.CipherTextG1.prototype.isPrototypeOf(c)) {
if (exports.CipherTextG1.prototype.isPrototypeOf(c)) {
dec = capi.sheDecG1
} else if (self.CipherTextG2.prototype.isPrototypeOf(c)) {
} else if (exports.CipherTextG2.prototype.isPrototypeOf(c)) {
dec = capi.sheDecG2
} else if (self.CipherTextGT.prototype.isPrototypeOf(c)) {
} else if (exports.CipherTextGT.prototype.isPrototypeOf(c)) {
dec = capi.sheDecGT
} else {
throw('self.SecretKey.dec:not supported')
throw('exports.SecretKey.dec:not supported')
}
return callDec(dec, this.a_, c.a_)
}
}
self.getSecretKeyFromHexStr = function(s) {
r = new self.SecretKey()
exports.getSecretKeyFromHexStr = function(s) {
r = new exports.SecretKey()
r.fromHexStr(s)
return r
}
self.PublicKey = class extends Common {
exports.PublicKey = class extends Common {
constructor() {
super(SHE_PUBLICKEY_SIZE)
}
@ -353,46 +394,46 @@
callSetter(capi.shePublicKeyDeserialize, this.a_, s)
}
encG1(m) {
return callEnc(capi.sheEnc32G1, self.CipherTextG1, this.a_, m)
return callEnc(capi.sheEnc32G1, exports.CipherTextG1, this.a_, m)
}
encG2(m) {
return callEnc(capi.sheEnc32G2, self.CipherTextG2, this.a_, m)
return callEnc(capi.sheEnc32G2, exports.CipherTextG2, this.a_, m)
}
encGT(m) {
return callEnc(capi.sheEnc32GT, self.CipherTextGT, this.a_, m)
return callEnc(capi.sheEnc32GT, exports.CipherTextGT, this.a_, m)
}
reRand(c) {
let reRand = null
if (self.CipherTextG1.prototype.isPrototypeOf(c)) {
if (exports.CipherTextG1.prototype.isPrototypeOf(c)) {
reRand = capi.sheReRandG1
} else if (self.CipherTextG2.prototype.isPrototypeOf(c)) {
} else if (exports.CipherTextG2.prototype.isPrototypeOf(c)) {
reRand = capi.sheReRandG2
} else if (self.CipherTextGT.prototype.isPrototypeOf(c)) {
} else if (exports.CipherTextGT.prototype.isPrototypeOf(c)) {
reRand = capi.sheReRandGT
} else {
throw('self.PublicKey.reRand:not supported')
throw('exports.PublicKey.reRand:not supported')
}
return callReRand(reRand, c.a_, this.a_)
}
convertToCipherTextGT(c) {
let convertFrom = null
if (self.CipherTextG1.prototype.isPrototypeOf(c)) {
if (exports.CipherTextG1.prototype.isPrototypeOf(c)) {
convertFrom = capi.sheConvertFromG1
} else if (self.CipherTextG2.prototype.isPrototypeOf(c)) {
} else if (exports.CipherTextG2.prototype.isPrototypeOf(c)) {
convertFrom = capi.sheConvertFromG2
} else {
throw('self.PublicKey.convertToCipherTextGT:not supported')
throw('exports.PublicKey.convertToCipherTextGT:not supported')
}
return callConvertFrom(convertFrom, this.a_, c.a_)
}
}
self.getPublicKeyFromHexStr = function(s) {
r = new self.PublicKey()
exports.getPublicKeyFromHexStr = function(s) {
r = new exports.PublicKey()
r.fromHexStr(s)
return r
}
self.CipherTextG1 = class extends Common {
exports.CipherTextG1 = class extends Common {
constructor() {
super(SHE_CIPHERTEXT_G1_SIZE)
}
@ -404,12 +445,12 @@
}
}
self.getCipherTextG1FromHexStr = function(s) {
r = new self.CipherTextG1()
exports.getCipherTextG1FromHexStr = function(s) {
r = new exports.CipherTextG1()
r.fromHexStr(s)
return r
}
self.CipherTextG2 = class extends Common {
exports.CipherTextG2 = class extends Common {
constructor() {
super(SHE_CIPHERTEXT_G2_SIZE)
}
@ -421,13 +462,13 @@
}
}
self.getCipherTextG2FromHexStr = function(s) {
r = new self.CipherTextG2()
exports.getCipherTextG2FromHexStr = function(s) {
r = new exports.CipherTextG2()
r.fromHexStr(s)
return r
}
self.CipherTextGT = class extends Common {
exports.CipherTextGT = class extends Common {
constructor() {
super(SHE_CIPHERTEXT_GT_SIZE)
}
@ -439,72 +480,72 @@
}
}
self.getCipherTextGTFromHexStr = function(s) {
r = new self.CipherTextGT()
exports.getCipherTextGTFromHexStr = function(s) {
r = new exports.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')
exports.add = function(x, y) {
if (x.a_.length != y.a_.length) throw('exports.add:bad type')
let add = null
let cstr = null
if (self.CipherTextG1.prototype.isPrototypeOf(x)) {
if (exports.CipherTextG1.prototype.isPrototypeOf(x)) {
add = capi.sheAddG1
cstr = self.CipherTextG1
} else if (self.CipherTextG2.prototype.isPrototypeOf(x)) {
cstr = exports.CipherTextG1
} else if (exports.CipherTextG2.prototype.isPrototypeOf(x)) {
add = capi.sheAddG2
cstr = self.CipherTextG2
} else if (self.CipherTextGT.prototype.isPrototypeOf(x)) {
cstr = exports.CipherTextG2
} else if (exports.CipherTextGT.prototype.isPrototypeOf(x)) {
add = capi.sheAddGT
cstr = self.CipherTextGT
cstr = exports.CipherTextGT
} else {
throw('self.add:not supported')
throw('exports.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')
exports.sub = function(x, y) {
if (x.a_.length != y.a_.length) throw('exports.sub:bad type')
let sub = null
let cstr = null
if (self.CipherTextG1.prototype.isPrototypeOf(x)) {
if (exports.CipherTextG1.prototype.isPrototypeOf(x)) {
sub = capi.sheSubG1
cstr = self.CipherTextG1
} else if (self.CipherTextG2.prototype.isPrototypeOf(x)) {
cstr = exports.CipherTextG1
} else if (exports.CipherTextG2.prototype.isPrototypeOf(x)) {
sub = capi.sheSubG2
cstr = self.CipherTextG2
} else if (self.CipherTextGT.prototype.isPrototypeOf(x)) {
cstr = exports.CipherTextG2
} else if (exports.CipherTextGT.prototype.isPrototypeOf(x)) {
sub = capi.sheSubGT
cstr = self.CipherTextGT
cstr = exports.CipherTextGT
} else {
throw('self.sub:not supported')
throw('exports.sub:not supported')
}
return callAddSub(sub, cstr, x.a_, y.a_)
}
// return x * (int)y
self.mulInt = function(x, y) {
exports.mulInt = function(x, y) {
let mulInt = null
let cstr = null
if (self.CipherTextG1.prototype.isPrototypeOf(x)) {
if (exports.CipherTextG1.prototype.isPrototypeOf(x)) {
mulInt = capi.sheMul32G1
cstr = self.CipherTextG1
} else if (self.CipherTextG2.prototype.isPrototypeOf(x)) {
cstr = exports.CipherTextG1
} else if (exports.CipherTextG2.prototype.isPrototypeOf(x)) {
mulInt = capi.sheMul32G2
cstr = self.CipherTextG2
} else if (self.CipherTextGT.prototype.isPrototypeOf(x)) {
cstr = exports.CipherTextG2
} else if (exports.CipherTextGT.prototype.isPrototypeOf(x)) {
mulInt = capi.sheMul32GT
cstr = self.CipherTextGT
cstr = exports.CipherTextGT
} else {
throw('self.mulInt:not supported')
throw('exports.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()
exports.mul = function(x, y) {
if (!exports.CipherTextG1.prototype.isPrototypeOf(x)
|| !exports.CipherTextG2.prototype.isPrototypeOf(y)) throw('exports.mul:bad type')
let z = new exports.CipherTextGT()
let stack = mod.Runtime.stackSave()
let xPos = mod.Runtime.stackAlloc(x.a_.length * 4)
let yPos = mod.Runtime.stackAlloc(y.a_.length * 4)
@ -517,24 +558,5 @@
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
return exports
})

Loading…
Cancel
Save