Phillip Lang Martinez
2 months ago
8 changed files with 739 additions and 136 deletions
@ -0,0 +1,266 @@
|
||||
// @ts-nocheck
|
||||
|
||||
/* |
||||
* ed2curve: convert Ed25519 signing key pair into Curve25519 |
||||
* key pair suitable for Diffie-Hellman key exchange. |
||||
* |
||||
* Written by Dmitry Chestnykh in 2014. Public domain. |
||||
*/ |
||||
/* jshint newcap: false */ |
||||
|
||||
/* |
||||
Change to es6 import/export |
||||
*/ |
||||
|
||||
import nacl from './nacl-fast' |
||||
|
||||
// (function(root, f) {
|
||||
// 'use strict';
|
||||
// if (typeof module !== 'undefined' && module.exports) module.exports = f(require('tweetnacl'));
|
||||
// else root.ed2curve = f(root.nacl);
|
||||
// }(this, function(nacl) {
|
||||
// 'use strict';
|
||||
// if (!nacl) throw new Error('tweetnacl not loaded');
|
||||
|
||||
// -- Operations copied from TweetNaCl.js. --
|
||||
|
||||
var gf = function(init) { |
||||
var i, r = new Float64Array(16); |
||||
if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; |
||||
return r; |
||||
}; |
||||
|
||||
var gf0 = gf(), |
||||
gf1 = gf([1]), |
||||
D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), |
||||
I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); |
||||
|
||||
function car25519(o) { |
||||
var c; |
||||
var i; |
||||
for (i = 0; i < 16; i++) { |
||||
o[i] += 65536; |
||||
c = Math.floor(o[i] / 65536); |
||||
o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0); |
||||
o[i] -= (c * 65536); |
||||
} |
||||
} |
||||
|
||||
function sel25519(p, q, b) { |
||||
var t, c = ~(b-1); |
||||
for (var i = 0; i < 16; i++) { |
||||
t = c & (p[i] ^ q[i]); |
||||
p[i] ^= t; |
||||
q[i] ^= t; |
||||
} |
||||
} |
||||
|
||||
function unpack25519(o, n) { |
||||
var i; |
||||
for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); |
||||
o[15] &= 0x7fff; |
||||
} |
||||
|
||||
// addition
|
||||
function A(o, a, b) { |
||||
var i; |
||||
for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0; |
||||
} |
||||
|
||||
// subtraction
|
||||
function Z(o, a, b) { |
||||
var i; |
||||
for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0; |
||||
} |
||||
|
||||
// multiplication
|
||||
function M(o, a, b) { |
||||
var i, j, t = new Float64Array(31); |
||||
for (i = 0; i < 31; i++) t[i] = 0; |
||||
for (i = 0; i < 16; i++) { |
||||
for (j = 0; j < 16; j++) { |
||||
t[i+j] += a[i] * b[j]; |
||||
} |
||||
} |
||||
for (i = 0; i < 15; i++) { |
||||
t[i] += 38 * t[i+16]; |
||||
} |
||||
for (i = 0; i < 16; i++) o[i] = t[i]; |
||||
car25519(o); |
||||
car25519(o); |
||||
} |
||||
|
||||
// squaring
|
||||
function S(o, a) { |
||||
M(o, a, a); |
||||
} |
||||
|
||||
// inversion
|
||||
function inv25519(o, i) { |
||||
var c = gf(); |
||||
var a; |
||||
for (a = 0; a < 16; a++) c[a] = i[a]; |
||||
for (a = 253; a >= 0; a--) { |
||||
S(c, c); |
||||
if(a !== 2 && a !== 4) M(c, c, i); |
||||
} |
||||
for (a = 0; a < 16; a++) o[a] = c[a]; |
||||
} |
||||
|
||||
function pack25519(o, n) { |
||||
var i, j, b; |
||||
var m = gf(), t = gf(); |
||||
for (i = 0; i < 16; i++) t[i] = n[i]; |
||||
car25519(t); |
||||
car25519(t); |
||||
car25519(t); |
||||
for (j = 0; j < 2; j++) { |
||||
m[0] = t[0] - 0xffed; |
||||
for (i = 1; i < 15; i++) { |
||||
m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); |
||||
m[i-1] &= 0xffff; |
||||
} |
||||
m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); |
||||
b = (m[15]>>16) & 1; |
||||
m[14] &= 0xffff; |
||||
sel25519(t, m, 1-b); |
||||
} |
||||
for (i = 0; i < 16; i++) { |
||||
o[2*i] = t[i] & 0xff; |
||||
o[2*i+1] = t[i] >> 8; |
||||
} |
||||
} |
||||
|
||||
function par25519(a) { |
||||
var d = new Uint8Array(32); |
||||
pack25519(d, a); |
||||
return d[0] & 1; |
||||
} |
||||
|
||||
function vn(x, xi, y, yi, n) { |
||||
var i, d = 0; |
||||
for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; |
||||
return (1 & ((d - 1) >>> 8)) - 1; |
||||
} |
||||
|
||||
function crypto_verify_32(x, xi, y, yi) { |
||||
return vn(x, xi, y, yi, 32); |
||||
} |
||||
|
||||
function neq25519(a, b) { |
||||
var c = new Uint8Array(32), d = new Uint8Array(32); |
||||
pack25519(c, a); |
||||
pack25519(d, b); |
||||
return crypto_verify_32(c, 0, d, 0); |
||||
} |
||||
|
||||
function pow2523(o, i) { |
||||
var c = gf(); |
||||
var a; |
||||
for (a = 0; a < 16; a++) c[a] = i[a]; |
||||
for (a = 250; a >= 0; a--) { |
||||
S(c, c); |
||||
if (a !== 1) M(c, c, i); |
||||
} |
||||
for (a = 0; a < 16; a++) o[a] = c[a]; |
||||
} |
||||
|
||||
function set25519(r, a) { |
||||
var i; |
||||
for (i = 0; i < 16; i++) r[i] = a[i] | 0; |
||||
} |
||||
|
||||
function unpackneg(r, p) { |
||||
var t = gf(), chk = gf(), num = gf(), |
||||
den = gf(), den2 = gf(), den4 = gf(), |
||||
den6 = gf(); |
||||
|
||||
set25519(r[2], gf1); |
||||
unpack25519(r[1], p); |
||||
S(num, r[1]); |
||||
M(den, num, D); |
||||
Z(num, num, r[2]); |
||||
A(den, r[2], den); |
||||
|
||||
S(den2, den); |
||||
S(den4, den2); |
||||
M(den6, den4, den2); |
||||
M(t, den6, num); |
||||
M(t, t, den); |
||||
|
||||
pow2523(t, t); |
||||
M(t, t, num); |
||||
M(t, t, den); |
||||
M(t, t, den); |
||||
M(r[0], t, den); |
||||
|
||||
S(chk, r[0]); |
||||
M(chk, chk, den); |
||||
if (neq25519(chk, num)) M(r[0], r[0], I); |
||||
|
||||
S(chk, r[0]); |
||||
M(chk, chk, den); |
||||
if (neq25519(chk, num)) return -1; |
||||
|
||||
if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0]); |
||||
|
||||
M(r[3], r[0], r[1]); |
||||
return 0; |
||||
} |
||||
|
||||
// ----
|
||||
|
||||
// Converts Ed25519 public key to Curve25519 public key.
|
||||
// montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p
|
||||
function convertPublicKey(pk) { |
||||
var z = new Uint8Array(32), |
||||
q = [gf(), gf(), gf(), gf()], |
||||
a = gf(), b = gf(); |
||||
|
||||
if (unpackneg(q, pk)) return null; // reject invalid key
|
||||
|
||||
var y = q[1]; |
||||
|
||||
A(a, gf1, y); |
||||
Z(b, gf1, y); |
||||
inv25519(b, b); |
||||
M(a, a, b); |
||||
|
||||
pack25519(z, a); |
||||
return z; |
||||
} |
||||
|
||||
// Converts Ed25519 secret key to Curve25519 secret key.
|
||||
function convertSecretKey(sk) { |
||||
var d = new Uint8Array(64), o = new Uint8Array(32), i; |
||||
nacl.lowlevel.crypto_hash(d, sk, 32); |
||||
d[0] &= 248; |
||||
d[31] &= 127; |
||||
d[31] |= 64; |
||||
for (i = 0; i < 32; i++) o[i] = d[i]; |
||||
for (i = 0; i < 64; i++) d[i] = 0; |
||||
return o; |
||||
} |
||||
|
||||
function convertKeyPair(edKeyPair) { |
||||
var publicKey = convertPublicKey(edKeyPair.publicKey); |
||||
if (!publicKey) return null; |
||||
return { |
||||
publicKey: publicKey, |
||||
secretKey: convertSecretKey(edKeyPair.secretKey) |
||||
}; |
||||
} |
||||
|
||||
// return {
|
||||
// convertPublicKey: convertPublicKey,
|
||||
// convertSecretKey: convertSecretKey,
|
||||
// convertKeyPair: convertKeyPair,
|
||||
// };
|
||||
|
||||
export default { |
||||
convertPublicKey: convertPublicKey, |
||||
convertSecretKey: convertSecretKey, |
||||
convertKeyPair: convertKeyPair, |
||||
} |
||||
|
||||
// }));
|
@ -0,0 +1,29 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import Base58 from '../deps/Base58' |
||||
import ed2curve from '../deps/ed2curve' |
||||
import nacl from '../deps/nacl-fast' |
||||
import {Sha256} from 'asmcrypto.js' |
||||
|
||||
|
||||
export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => { |
||||
const test = encryptedMessage |
||||
let _encryptedMessage = Base58.decode(encryptedMessage) |
||||
const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey |
||||
const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey) |
||||
|
||||
const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference) |
||||
|
||||
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) |
||||
const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey) |
||||
const sharedSecret = new Uint8Array(32); |
||||
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey) |
||||
|
||||
const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result |
||||
const _decryptedMessage = nacl.secretbox.open(_encryptedMessage, _lastReference.slice(0, 24), _chatEncryptionSeed) |
||||
|
||||
let decryptedMessage = '' |
||||
|
||||
_decryptedMessage === false ? decryptedMessage : decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage) |
||||
return decryptedMessage |
||||
} |
Loading…
Reference in new issue