Implement hashing

This commit is contained in:
Yingtong Li 2017-09-25 15:53:58 +10:00
parent 0a6831b366
commit 3fad40dec2
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
4 changed files with 61 additions and 3 deletions

View File

@ -14,14 +14,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Load json.js
# Load json.js, jssha-sha256.js
lib = __pragma__('js', '''
(function() {{
var exports = {{}};
{}
{}
var exports = {{}};
exports.stringify = stringify_main;
exports.jsSHA = window.jsSHA;
return exports;
}})()''', __include__('eos/core/objects/json.js'))
}})()''', __include__('eos/core/objects/json.js'), __include__('eos/core/objects/jssha-sha256.js'))
# Fields
# ======
@ -106,6 +108,10 @@ class EosObject(metaclass=EosObjectType):
return self._instance[0].recurse_parents(cls)
return None
#@property
def hash(self):
return EosObject.to_sha256(EosObject.serialise_and_wrap(self))
@staticmethod
def serialise_and_wrap(value, object_type=None):
if object_type:
@ -127,6 +133,13 @@ class EosObject(metaclass=EosObjectType):
@staticmethod
def from_json(value):
return JSON.parse(value)
@staticmethod
def to_sha256(value):
# TNYI: This is completely borked
sha_obj = __pragma__('js', '{}', 'new lib.jsSHA("SHA-256", "TEXT")')
sha_obj.js_update(value)
return sha_obj.getHash('B64')
class EosList(EosObject):
def __init__(self, *args):

View File

@ -0,0 +1,29 @@
/*
A JavaScript implementation of the SHA family of hashes, as
defined in FIPS PUB 180-4 and FIPS PUB 202, as well as the corresponding
HMAC implementation as defined in FIPS PUB 198a
Copyright Brian Turek 2008-2017
Distributed under the BSD License
See http://caligatio.github.com/jsSHA/ for more information
Several functions taken from Paul Johnston
*/
'use strict';(function(I){function w(c,a,d){var k=0,b=[],g=0,f,n,h,e,m,q,y,p,l=!1,t=[],r=[],u,z=!1;d=d||{};f=d.encoding||"UTF8";u=d.numRounds||1;if(u!==parseInt(u,10)||1>u)throw Error("numRounds must a integer >= 1");if(0===c.lastIndexOf("SHA-",0))if(q=function(b,a){return A(b,a,c)},y=function(b,a,k,f){var g,e;if("SHA-224"===c||"SHA-256"===c)g=(a+65>>>9<<4)+15,e=16;else throw Error("Unexpected error in SHA-2 implementation");for(;b.length<=g;)b.push(0);b[a>>>5]|=128<<24-a%32;a=a+k;b[g]=a&4294967295;
b[g-1]=a/4294967296|0;k=b.length;for(a=0;a<k;a+=e)f=A(b.slice(a,a+e),f,c);if("SHA-224"===c)b=[f[0],f[1],f[2],f[3],f[4],f[5],f[6]];else if("SHA-256"===c)b=f;else throw Error("Unexpected error in SHA-2 implementation");return b},p=function(b){return b.slice()},"SHA-224"===c)m=512,e=224;else if("SHA-256"===c)m=512,e=256;else throw Error("Chosen SHA variant is not supported");else throw Error("Chosen SHA variant is not supported");h=B(a,f);n=x(c);this.setHMACKey=function(b,a,g){var e;if(!0===l)throw Error("HMAC key already set");
if(!0===z)throw Error("Cannot set HMAC key after calling update");f=(g||{}).encoding||"UTF8";a=B(a,f)(b);b=a.binLen;a=a.value;e=m>>>3;g=e/4-1;if(e<b/8){for(a=y(a,b,0,x(c));a.length<=g;)a.push(0);a[g]&=4294967040}else if(e>b/8){for(;a.length<=g;)a.push(0);a[g]&=4294967040}for(b=0;b<=g;b+=1)t[b]=a[b]^909522486,r[b]=a[b]^1549556828;n=q(t,n);k=m;l=!0};this.update=function(a){var c,f,e,d=0,p=m>>>5;c=h(a,b,g);a=c.binLen;f=c.value;c=a>>>5;for(e=0;e<c;e+=p)d+m<=a&&(n=q(f.slice(e,e+p),n),d+=m);k+=d;b=f.slice(d>>>
5);g=a%m;z=!0};this.getHash=function(a,f){var d,h,m,q;if(!0===l)throw Error("Cannot call getHash after setting HMAC key");m=C(f);switch(a){case "HEX":d=function(a){return D(a,e,m)};break;case "B64":d=function(a){return E(a,e,m)};break;case "BYTES":d=function(a){return F(a,e)};break;case "ARRAYBUFFER":try{h=new ArrayBuffer(0)}catch(v){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a){return G(a,e)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER");
}q=y(b.slice(),g,k,p(n));for(h=1;h<u;h+=1)q=y(q,e,0,x(c));return d(q)};this.getHMAC=function(a,f){var d,h,t,u;if(!1===l)throw Error("Cannot call getHMAC without first setting HMAC key");t=C(f);switch(a){case "HEX":d=function(a){return D(a,e,t)};break;case "B64":d=function(a){return E(a,e,t)};break;case "BYTES":d=function(a){return F(a,e)};break;case "ARRAYBUFFER":try{d=new ArrayBuffer(0)}catch(v){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a){return G(a,e)};break;default:throw Error("outputFormat must be HEX, B64, BYTES, or ARRAYBUFFER");
}h=y(b.slice(),g,k,p(n));u=q(r,x(c));u=y(h,e,m,u);return d(u)}}function l(){}function D(c,a,d){var k="";a/=8;var b,g;for(b=0;b<a;b+=1)g=c[b>>>2]>>>8*(3+b%4*-1),k+="0123456789abcdef".charAt(g>>>4&15)+"0123456789abcdef".charAt(g&15);return d.outputUpper?k.toUpperCase():k}function E(c,a,d){var k="",b=a/8,g,f,n;for(g=0;g<b;g+=3)for(f=g+1<b?c[g+1>>>2]:0,n=g+2<b?c[g+2>>>2]:0,n=(c[g>>>2]>>>8*(3+g%4*-1)&255)<<16|(f>>>8*(3+(g+1)%4*-1)&255)<<8|n>>>8*(3+(g+2)%4*-1)&255,f=0;4>f;f+=1)8*g+6*f<=a?k+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(n>>>
6*(3-f)&63):k+=d.b64Pad;return k}function F(c,a){var d="",k=a/8,b,g;for(b=0;b<k;b+=1)g=c[b>>>2]>>>8*(3+b%4*-1)&255,d+=String.fromCharCode(g);return d}function G(c,a){var d=a/8,k,b=new ArrayBuffer(d);for(k=0;k<d;k+=1)b[k]=c[k>>>2]>>>8*(3+k%4*-1)&255;return b}function C(c){var a={outputUpper:!1,b64Pad:"=",shakeLen:-1};c=c||{};a.outputUpper=c.outputUpper||!1;!0===c.hasOwnProperty("b64Pad")&&(a.b64Pad=c.b64Pad);if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==
typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function B(c,a){var d;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(c){case "HEX":d=function(a,b,c){var f=a.length,d,h,e,m,q;if(0!==f%2)throw Error("String of HEX type must be in byte increments");b=b||[0];c=c||0;q=c>>>3;for(d=0;d<f;d+=2){h=parseInt(a.substr(d,2),16);if(isNaN(h))throw Error("String of HEX type contains invalid characters");
m=(d>>>1)+q;for(e=m>>>2;b.length<=e;)b.push(0);b[e]|=h<<8*(3+m%4*-1)}return{value:b,binLen:4*f+c}};break;case "TEXT":d=function(c,b,d){var f,n,h=0,e,m,q,l,p,r;b=b||[0];d=d||0;q=d>>>3;if("UTF8"===a)for(r=3,e=0;e<c.length;e+=1)for(f=c.charCodeAt(e),n=[],128>f?n.push(f):2048>f?(n.push(192|f>>>6),n.push(128|f&63)):55296>f||57344<=f?n.push(224|f>>>12,128|f>>>6&63,128|f&63):(e+=1,f=65536+((f&1023)<<10|c.charCodeAt(e)&1023),n.push(240|f>>>18,128|f>>>12&63,128|f>>>6&63,128|f&63)),m=0;m<n.length;m+=1){p=h+
q;for(l=p>>>2;b.length<=l;)b.push(0);b[l]|=n[m]<<8*(r+p%4*-1);h+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(r=2,e=0;e<c.length;e+=1){f=c.charCodeAt(e);"UTF16LE"===a&&(m=f&255,f=m<<8|f>>>8);p=h+q;for(l=p>>>2;b.length<=l;)b.push(0);b[l]|=f<<8*(r+p%4*-1);h+=2}return{value:b,binLen:8*h+d}};break;case "B64":d=function(a,b,c){var f=0,d,h,e,m,q,l,p;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");h=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==h&&h<a.length)throw Error("Invalid '=' found in base-64 string");
b=b||[0];c=c||0;l=c>>>3;for(h=0;h<a.length;h+=4){q=a.substr(h,4);for(e=m=0;e<q.length;e+=1)d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(q[e]),m|=d<<18-6*e;for(e=0;e<q.length-1;e+=1){p=f+l;for(d=p>>>2;b.length<=d;)b.push(0);b[d]|=(m>>>16-8*e&255)<<8*(3+p%4*-1);f+=1}}return{value:b,binLen:8*f+c}};break;case "BYTES":d=function(a,b,c){var d,n,h,e,m;b=b||[0];c=c||0;h=c>>>3;for(n=0;n<a.length;n+=1)d=a.charCodeAt(n),m=n+h,e=m>>>2,b.length<=e&&b.push(0),b[e]|=d<<8*(3+m%4*-1);
return{value:b,binLen:8*a.length+c}};break;case "ARRAYBUFFER":try{d=new ArrayBuffer(0)}catch(k){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a,b,c){var d,n,h,e;b=b||[0];c=c||0;n=c>>>3;for(d=0;d<a.byteLength;d+=1)e=d+n,h=e>>>2,b.length<=h&&b.push(0),b[h]|=a[d]<<8*(3+e%4*-1);return{value:b,binLen:8*a.byteLength+c}};break;default:throw Error("format must be HEX, TEXT, B64, BYTES, or ARRAYBUFFER");}return d}function r(c,a){return c>>>a|c<<32-a}function J(c,a,d){return c&a^
~c&d}function K(c,a,d){return c&a^c&d^a&d}function L(c){return r(c,2)^r(c,13)^r(c,22)}function M(c){return r(c,6)^r(c,11)^r(c,25)}function N(c){return r(c,7)^r(c,18)^c>>>3}function O(c){return r(c,17)^r(c,19)^c>>>10}function P(c,a){var d=(c&65535)+(a&65535);return((c>>>16)+(a>>>16)+(d>>>16)&65535)<<16|d&65535}function Q(c,a,d,k){var b=(c&65535)+(a&65535)+(d&65535)+(k&65535);return((c>>>16)+(a>>>16)+(d>>>16)+(k>>>16)+(b>>>16)&65535)<<16|b&65535}function R(c,a,d,k,b){var g=(c&65535)+(a&65535)+(d&65535)+
(k&65535)+(b&65535);return((c>>>16)+(a>>>16)+(d>>>16)+(k>>>16)+(b>>>16)+(g>>>16)&65535)<<16|g&65535}function x(c){var a=[],d;if(0===c.lastIndexOf("SHA-",0))switch(a=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428],d=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],c){case "SHA-224":break;case "SHA-256":a=d;break;case "SHA-384":a=[new l,new l,new l,new l,new l,new l,new l,new l];break;case "SHA-512":a=[new l,new l,new l,
new l,new l,new l,new l,new l];break;default:throw Error("Unknown SHA variant");}else throw Error("No SHA variants supported");return a}function A(c,a,d){var k,b,g,f,n,h,e,m,l,r,p,w,t,x,u,z,A,B,C,D,E,F,v=[],G;if("SHA-224"===d||"SHA-256"===d)r=64,w=1,F=Number,t=P,x=Q,u=R,z=N,A=O,B=L,C=M,E=K,D=J,G=H;else throw Error("Unexpected error in SHA-2 implementation");d=a[0];k=a[1];b=a[2];g=a[3];f=a[4];n=a[5];h=a[6];e=a[7];for(p=0;p<r;p+=1)16>p?(l=p*w,m=c.length<=l?0:c[l],l=c.length<=l+1?0:c[l+1],v[p]=new F(m,
l)):v[p]=x(A(v[p-2]),v[p-7],z(v[p-15]),v[p-16]),m=u(e,C(f),D(f,n,h),G[p],v[p]),l=t(B(d),E(d,k,b)),e=h,h=n,n=f,f=t(g,m),g=b,b=k,k=d,d=t(m,l);a[0]=t(d,a[0]);a[1]=t(k,a[1]);a[2]=t(b,a[2]);a[3]=t(g,a[3]);a[4]=t(f,a[4]);a[5]=t(n,a[5]);a[6]=t(h,a[6]);a[7]=t(e,a[7]);return a}var H;H=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,
1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];"function"===typeof define&&define.amd?
define(function(){return w}):"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(module.exports=w),exports=w):I.jsSHA=w})(window);

View File

@ -17,6 +17,8 @@
import pymongo
from bson.binary import UUIDLegacy
import base64
import hashlib
import json
import uuid
@ -117,6 +119,10 @@ class EosObject(metaclass=EosObjectType):
return self._instance[0].recurse_parents(cls)
return None
#@property
def hash(self):
return EosObject.to_sha256(EosObject.serialise_and_wrap(self))
@staticmethod
def serialise_and_wrap(value, object_type=None):
if object_type:
@ -136,6 +142,12 @@ class EosObject(metaclass=EosObjectType):
@staticmethod
def from_json(value):
return json.loads(value)
@staticmethod
def to_sha256(value):
sha_obj = hashlib.sha256()
sha_obj.update(value.encode('utf-8'))
return base64.b64encode(sha_obj.digest()).decode('utf-8')
class EosList(EosObject, list):
def append(self, value):

View File

@ -81,6 +81,10 @@ class ObjectTestCase(EosTestCase):
#self.assertEqual(EosObject.deserialise_and_unwrap(expect1a), person1)
self.assertEqualJSON(EosObject.deserialise_and_unwrap(expect1a).serialise(), person1.serialise())
class HashTestCase(EosTestCase):
def test_hash(self):
self.assertEqual(EosObject.to_sha256('Hello World!'), 'f4OxZX/x/FO5LcGBSKHWXfwtSx+j1ncoSt3SABJtkGk=')
class BigIntTestCase(EosTestCase):
def test_basic(self):
bigint1 = BigInt(5)