URI: 
       tripemd.py - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
       tripemd.py (14679B)
       ---
            1 ## ripemd.py - pure Python implementation of the RIPEMD-160 algorithm.
            2 ## Bjorn Edstrom <be@bjrn.se> 16 december 2007.
            3 ##
            4 ## Copyrights
            5 ## ==========
            6 ##
            7 ## This code is a derived from an implementation by Markus Friedl which is
            8 ## subject to the following license. This Python implementation is not
            9 ## subject to any other license.
           10 ##
           11 ##/*
           12 ## * Copyright (c) 2001 Markus Friedl.  All rights reserved.
           13 ## *
           14 ## * Redistribution and use in source and binary forms, with or without
           15 ## * modification, are permitted provided that the following conditions
           16 ## * are met:
           17 ## * 1. Redistributions of source code must retain the above copyright
           18 ## *    notice, this list of conditions and the following disclaimer.
           19 ## * 2. Redistributions in binary form must reproduce the above copyright
           20 ## *    notice, this list of conditions and the following disclaimer in the
           21 ## *    documentation and/or other materials provided with the distribution.
           22 ## *
           23 ## * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
           24 ## * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
           25 ## * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
           26 ## * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
           27 ## * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
           28 ## * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
           29 ## * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
           30 ## * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
           31 ## * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
           32 ## * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
           33 ## */
           34 ##/*
           35 ## * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
           36 ## * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
           37 ## * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
           38 ## */
           39 
           40 #block_size = 1
           41 digest_size = 20
           42 digestsize = 20
           43 
           44 class RIPEMD160:
           45     """Return a new RIPEMD160 object. An optional string argument
           46     may be provided; if present, this string will be automatically
           47     hashed."""
           48 
           49     def __init__(self, arg=None):
           50         self.ctx = RMDContext()
           51         if arg:
           52             self.update(arg)
           53         self.dig = None
           54 
           55     def update(self, arg):
           56         """update(arg)"""
           57         RMD160Update(self.ctx, arg, len(arg))
           58         self.dig = None
           59 
           60     def digest(self):
           61         """digest()"""
           62         if self.dig:
           63             return self.dig
           64         ctx = self.ctx.copy()
           65         self.dig = RMD160Final(self.ctx)
           66         self.ctx = ctx
           67         return self.dig
           68 
           69     def hexdigest(self):
           70         """hexdigest()"""
           71         dig = self.digest()
           72         hex_digest = ''
           73         for d in dig:
           74             hex_digest += '%02x' % d
           75         return hex_digest
           76 
           77     def copy(self):
           78         """copy()"""
           79         import copy
           80         return copy.deepcopy(self)
           81 
           82 
           83 
           84 def new(arg=None):
           85     """Return a new RIPEMD160 object. An optional string argument
           86     may be provided; if present, this string will be automatically
           87     hashed."""
           88     return RIPEMD160(arg)
           89 
           90 
           91 
           92 #
           93 # Private.
           94 #
           95 
           96 class RMDContext:
           97     def __init__(self):
           98         self.state = [0x67452301, 0xEFCDAB89, 0x98BADCFE,
           99                       0x10325476, 0xC3D2E1F0] # uint32
          100         self.count = 0 # uint64
          101         self.buffer = [0]*64 # uchar
          102     def copy(self):
          103         ctx = RMDContext()
          104         ctx.state = self.state[:]
          105         ctx.count = self.count
          106         ctx.buffer = self.buffer[:]
          107         return ctx
          108 
          109 K0 = 0x00000000
          110 K1 = 0x5A827999
          111 K2 = 0x6ED9EBA1
          112 K3 = 0x8F1BBCDC
          113 K4 = 0xA953FD4E
          114 
          115 KK0 = 0x50A28BE6
          116 KK1 = 0x5C4DD124
          117 KK2 = 0x6D703EF3
          118 KK3 = 0x7A6D76E9
          119 KK4 = 0x00000000
          120 
          121 def ROL(n, x):
          122     return ((x << n) & 0xffffffff) | (x >> (32 - n))
          123 
          124 def F0(x, y, z):
          125     return x ^ y ^ z
          126 
          127 def F1(x, y, z):
          128     return (x & y) | (((~x) % 0x100000000) & z)
          129 
          130 def F2(x, y, z):
          131     return (x | ((~y) % 0x100000000)) ^ z
          132 
          133 def F3(x, y, z):
          134     return (x & z) | (((~z) % 0x100000000) & y)
          135 
          136 def F4(x, y, z):
          137     return x ^ (y | ((~z) % 0x100000000))
          138 
          139 def R(a, b, c, d, e, Fj, Kj, sj, rj, X):
          140     a = ROL(sj, (a + Fj(b, c, d) + X[rj] + Kj) % 0x100000000) + e
          141     c = ROL(10, c)
          142     return a % 0x100000000, c
          143 
          144 PADDING = [0x80] + [0]*63
          145 
          146 import sys
          147 import struct
          148 
          149 def RMD160Transform(state, block): #uint32 state[5], uchar block[64]
          150     x = [0]*16
          151     if sys.byteorder == 'little':
          152         x = struct.unpack('<16L', bytes([x for x in block[0:64]]))
          153     else:
          154         raise "Error!!"
          155     a = state[0]
          156     b = state[1]
          157     c = state[2]
          158     d = state[3]
          159     e = state[4]
          160 
          161     #/* Round 1 */
          162     a, c = R(a, b, c, d, e, F0, K0, 11,  0, x);
          163     e, b = R(e, a, b, c, d, F0, K0, 14,  1, x);
          164     d, a = R(d, e, a, b, c, F0, K0, 15,  2, x);
          165     c, e = R(c, d, e, a, b, F0, K0, 12,  3, x);
          166     b, d = R(b, c, d, e, a, F0, K0,  5,  4, x);
          167     a, c = R(a, b, c, d, e, F0, K0,  8,  5, x);
          168     e, b = R(e, a, b, c, d, F0, K0,  7,  6, x);
          169     d, a = R(d, e, a, b, c, F0, K0,  9,  7, x);
          170     c, e = R(c, d, e, a, b, F0, K0, 11,  8, x);
          171     b, d = R(b, c, d, e, a, F0, K0, 13,  9, x);
          172     a, c = R(a, b, c, d, e, F0, K0, 14, 10, x);
          173     e, b = R(e, a, b, c, d, F0, K0, 15, 11, x);
          174     d, a = R(d, e, a, b, c, F0, K0,  6, 12, x);
          175     c, e = R(c, d, e, a, b, F0, K0,  7, 13, x);
          176     b, d = R(b, c, d, e, a, F0, K0,  9, 14, x);
          177     a, c = R(a, b, c, d, e, F0, K0,  8, 15, x); #/* #15 */
          178     #/* Round 2 */
          179     e, b = R(e, a, b, c, d, F1, K1,  7,  7, x);
          180     d, a = R(d, e, a, b, c, F1, K1,  6,  4, x);
          181     c, e = R(c, d, e, a, b, F1, K1,  8, 13, x);
          182     b, d = R(b, c, d, e, a, F1, K1, 13,  1, x);
          183     a, c = R(a, b, c, d, e, F1, K1, 11, 10, x);
          184     e, b = R(e, a, b, c, d, F1, K1,  9,  6, x);
          185     d, a = R(d, e, a, b, c, F1, K1,  7, 15, x);
          186     c, e = R(c, d, e, a, b, F1, K1, 15,  3, x);
          187     b, d = R(b, c, d, e, a, F1, K1,  7, 12, x);
          188     a, c = R(a, b, c, d, e, F1, K1, 12,  0, x);
          189     e, b = R(e, a, b, c, d, F1, K1, 15,  9, x);
          190     d, a = R(d, e, a, b, c, F1, K1,  9,  5, x);
          191     c, e = R(c, d, e, a, b, F1, K1, 11,  2, x);
          192     b, d = R(b, c, d, e, a, F1, K1,  7, 14, x);
          193     a, c = R(a, b, c, d, e, F1, K1, 13, 11, x);
          194     e, b = R(e, a, b, c, d, F1, K1, 12,  8, x); #/* #31 */
          195     #/* Round 3 */
          196     d, a = R(d, e, a, b, c, F2, K2, 11,  3, x);
          197     c, e = R(c, d, e, a, b, F2, K2, 13, 10, x);
          198     b, d = R(b, c, d, e, a, F2, K2,  6, 14, x);
          199     a, c = R(a, b, c, d, e, F2, K2,  7,  4, x);
          200     e, b = R(e, a, b, c, d, F2, K2, 14,  9, x);
          201     d, a = R(d, e, a, b, c, F2, K2,  9, 15, x);
          202     c, e = R(c, d, e, a, b, F2, K2, 13,  8, x);
          203     b, d = R(b, c, d, e, a, F2, K2, 15,  1, x);
          204     a, c = R(a, b, c, d, e, F2, K2, 14,  2, x);
          205     e, b = R(e, a, b, c, d, F2, K2,  8,  7, x);
          206     d, a = R(d, e, a, b, c, F2, K2, 13,  0, x);
          207     c, e = R(c, d, e, a, b, F2, K2,  6,  6, x);
          208     b, d = R(b, c, d, e, a, F2, K2,  5, 13, x);
          209     a, c = R(a, b, c, d, e, F2, K2, 12, 11, x);
          210     e, b = R(e, a, b, c, d, F2, K2,  7,  5, x);
          211     d, a = R(d, e, a, b, c, F2, K2,  5, 12, x); #/* #47 */
          212     #/* Round 4 */
          213     c, e = R(c, d, e, a, b, F3, K3, 11,  1, x);
          214     b, d = R(b, c, d, e, a, F3, K3, 12,  9, x);
          215     a, c = R(a, b, c, d, e, F3, K3, 14, 11, x);
          216     e, b = R(e, a, b, c, d, F3, K3, 15, 10, x);
          217     d, a = R(d, e, a, b, c, F3, K3, 14,  0, x);
          218     c, e = R(c, d, e, a, b, F3, K3, 15,  8, x);
          219     b, d = R(b, c, d, e, a, F3, K3,  9, 12, x);
          220     a, c = R(a, b, c, d, e, F3, K3,  8,  4, x);
          221     e, b = R(e, a, b, c, d, F3, K3,  9, 13, x);
          222     d, a = R(d, e, a, b, c, F3, K3, 14,  3, x);
          223     c, e = R(c, d, e, a, b, F3, K3,  5,  7, x);
          224     b, d = R(b, c, d, e, a, F3, K3,  6, 15, x);
          225     a, c = R(a, b, c, d, e, F3, K3,  8, 14, x);
          226     e, b = R(e, a, b, c, d, F3, K3,  6,  5, x);
          227     d, a = R(d, e, a, b, c, F3, K3,  5,  6, x);
          228     c, e = R(c, d, e, a, b, F3, K3, 12,  2, x); #/* #63 */
          229     #/* Round 5 */
          230     b, d = R(b, c, d, e, a, F4, K4,  9,  4, x);
          231     a, c = R(a, b, c, d, e, F4, K4, 15,  0, x);
          232     e, b = R(e, a, b, c, d, F4, K4,  5,  5, x);
          233     d, a = R(d, e, a, b, c, F4, K4, 11,  9, x);
          234     c, e = R(c, d, e, a, b, F4, K4,  6,  7, x);
          235     b, d = R(b, c, d, e, a, F4, K4,  8, 12, x);
          236     a, c = R(a, b, c, d, e, F4, K4, 13,  2, x);
          237     e, b = R(e, a, b, c, d, F4, K4, 12, 10, x);
          238     d, a = R(d, e, a, b, c, F4, K4,  5, 14, x);
          239     c, e = R(c, d, e, a, b, F4, K4, 12,  1, x);
          240     b, d = R(b, c, d, e, a, F4, K4, 13,  3, x);
          241     a, c = R(a, b, c, d, e, F4, K4, 14,  8, x);
          242     e, b = R(e, a, b, c, d, F4, K4, 11, 11, x);
          243     d, a = R(d, e, a, b, c, F4, K4,  8,  6, x);
          244     c, e = R(c, d, e, a, b, F4, K4,  5, 15, x);
          245     b, d = R(b, c, d, e, a, F4, K4,  6, 13, x); #/* #79 */
          246 
          247     aa = a;
          248     bb = b;
          249     cc = c;
          250     dd = d;
          251     ee = e;
          252 
          253     a = state[0]
          254     b = state[1]
          255     c = state[2]
          256     d = state[3]
          257     e = state[4]
          258 
          259     #/* Parallel round 1 */
          260     a, c = R(a, b, c, d, e, F4, KK0,  8,  5, x)
          261     e, b = R(e, a, b, c, d, F4, KK0,  9, 14, x)
          262     d, a = R(d, e, a, b, c, F4, KK0,  9,  7, x)
          263     c, e = R(c, d, e, a, b, F4, KK0, 11,  0, x)
          264     b, d = R(b, c, d, e, a, F4, KK0, 13,  9, x)
          265     a, c = R(a, b, c, d, e, F4, KK0, 15,  2, x)
          266     e, b = R(e, a, b, c, d, F4, KK0, 15, 11, x)
          267     d, a = R(d, e, a, b, c, F4, KK0,  5,  4, x)
          268     c, e = R(c, d, e, a, b, F4, KK0,  7, 13, x)
          269     b, d = R(b, c, d, e, a, F4, KK0,  7,  6, x)
          270     a, c = R(a, b, c, d, e, F4, KK0,  8, 15, x)
          271     e, b = R(e, a, b, c, d, F4, KK0, 11,  8, x)
          272     d, a = R(d, e, a, b, c, F4, KK0, 14,  1, x)
          273     c, e = R(c, d, e, a, b, F4, KK0, 14, 10, x)
          274     b, d = R(b, c, d, e, a, F4, KK0, 12,  3, x)
          275     a, c = R(a, b, c, d, e, F4, KK0,  6, 12, x) #/* #15 */
          276     #/* Parallel round 2 */
          277     e, b = R(e, a, b, c, d, F3, KK1,  9,  6, x)
          278     d, a = R(d, e, a, b, c, F3, KK1, 13, 11, x)
          279     c, e = R(c, d, e, a, b, F3, KK1, 15,  3, x)
          280     b, d = R(b, c, d, e, a, F3, KK1,  7,  7, x)
          281     a, c = R(a, b, c, d, e, F3, KK1, 12,  0, x)
          282     e, b = R(e, a, b, c, d, F3, KK1,  8, 13, x)
          283     d, a = R(d, e, a, b, c, F3, KK1,  9,  5, x)
          284     c, e = R(c, d, e, a, b, F3, KK1, 11, 10, x)
          285     b, d = R(b, c, d, e, a, F3, KK1,  7, 14, x)
          286     a, c = R(a, b, c, d, e, F3, KK1,  7, 15, x)
          287     e, b = R(e, a, b, c, d, F3, KK1, 12,  8, x)
          288     d, a = R(d, e, a, b, c, F3, KK1,  7, 12, x)
          289     c, e = R(c, d, e, a, b, F3, KK1,  6,  4, x)
          290     b, d = R(b, c, d, e, a, F3, KK1, 15,  9, x)
          291     a, c = R(a, b, c, d, e, F3, KK1, 13,  1, x)
          292     e, b = R(e, a, b, c, d, F3, KK1, 11,  2, x) #/* #31 */
          293     #/* Parallel round 3 */
          294     d, a = R(d, e, a, b, c, F2, KK2,  9, 15, x)
          295     c, e = R(c, d, e, a, b, F2, KK2,  7,  5, x)
          296     b, d = R(b, c, d, e, a, F2, KK2, 15,  1, x)
          297     a, c = R(a, b, c, d, e, F2, KK2, 11,  3, x)
          298     e, b = R(e, a, b, c, d, F2, KK2,  8,  7, x)
          299     d, a = R(d, e, a, b, c, F2, KK2,  6, 14, x)
          300     c, e = R(c, d, e, a, b, F2, KK2,  6,  6, x)
          301     b, d = R(b, c, d, e, a, F2, KK2, 14,  9, x)
          302     a, c = R(a, b, c, d, e, F2, KK2, 12, 11, x)
          303     e, b = R(e, a, b, c, d, F2, KK2, 13,  8, x)
          304     d, a = R(d, e, a, b, c, F2, KK2,  5, 12, x)
          305     c, e = R(c, d, e, a, b, F2, KK2, 14,  2, x)
          306     b, d = R(b, c, d, e, a, F2, KK2, 13, 10, x)
          307     a, c = R(a, b, c, d, e, F2, KK2, 13,  0, x)
          308     e, b = R(e, a, b, c, d, F2, KK2,  7,  4, x)
          309     d, a = R(d, e, a, b, c, F2, KK2,  5, 13, x) #/* #47 */
          310     #/* Parallel round 4 */
          311     c, e = R(c, d, e, a, b, F1, KK3, 15,  8, x)
          312     b, d = R(b, c, d, e, a, F1, KK3,  5,  6, x)
          313     a, c = R(a, b, c, d, e, F1, KK3,  8,  4, x)
          314     e, b = R(e, a, b, c, d, F1, KK3, 11,  1, x)
          315     d, a = R(d, e, a, b, c, F1, KK3, 14,  3, x)
          316     c, e = R(c, d, e, a, b, F1, KK3, 14, 11, x)
          317     b, d = R(b, c, d, e, a, F1, KK3,  6, 15, x)
          318     a, c = R(a, b, c, d, e, F1, KK3, 14,  0, x)
          319     e, b = R(e, a, b, c, d, F1, KK3,  6,  5, x)
          320     d, a = R(d, e, a, b, c, F1, KK3,  9, 12, x)
          321     c, e = R(c, d, e, a, b, F1, KK3, 12,  2, x)
          322     b, d = R(b, c, d, e, a, F1, KK3,  9, 13, x)
          323     a, c = R(a, b, c, d, e, F1, KK3, 12,  9, x)
          324     e, b = R(e, a, b, c, d, F1, KK3,  5,  7, x)
          325     d, a = R(d, e, a, b, c, F1, KK3, 15, 10, x)
          326     c, e = R(c, d, e, a, b, F1, KK3,  8, 14, x) #/* #63 */
          327     #/* Parallel round 5 */
          328     b, d = R(b, c, d, e, a, F0, KK4,  8, 12, x)
          329     a, c = R(a, b, c, d, e, F0, KK4,  5, 15, x)
          330     e, b = R(e, a, b, c, d, F0, KK4, 12, 10, x)
          331     d, a = R(d, e, a, b, c, F0, KK4,  9,  4, x)
          332     c, e = R(c, d, e, a, b, F0, KK4, 12,  1, x)
          333     b, d = R(b, c, d, e, a, F0, KK4,  5,  5, x)
          334     a, c = R(a, b, c, d, e, F0, KK4, 14,  8, x)
          335     e, b = R(e, a, b, c, d, F0, KK4,  6,  7, x)
          336     d, a = R(d, e, a, b, c, F0, KK4,  8,  6, x)
          337     c, e = R(c, d, e, a, b, F0, KK4, 13,  2, x)
          338     b, d = R(b, c, d, e, a, F0, KK4,  6, 13, x)
          339     a, c = R(a, b, c, d, e, F0, KK4,  5, 14, x)
          340     e, b = R(e, a, b, c, d, F0, KK4, 15,  0, x)
          341     d, a = R(d, e, a, b, c, F0, KK4, 13,  3, x)
          342     c, e = R(c, d, e, a, b, F0, KK4, 11,  9, x)
          343     b, d = R(b, c, d, e, a, F0, KK4, 11, 11, x) #/* #79 */
          344 
          345     t = (state[1] + cc + d) % 0x100000000;
          346     state[1] = (state[2] + dd + e) % 0x100000000;
          347     state[2] = (state[3] + ee + a) % 0x100000000;
          348     state[3] = (state[4] + aa + b) % 0x100000000;
          349     state[4] = (state[0] + bb + c) % 0x100000000;
          350     state[0] = t % 0x100000000;
          351 
          352     pass
          353 
          354 
          355 def RMD160Update(ctx, inp, inplen):
          356     if type(inp) == str:
          357         inp = [ord(i)&0xff for i in inp]
          358 
          359     have = (ctx.count // 8) % 64
          360     need = 64 - have
          361     ctx.count += 8 * inplen
          362     off = 0
          363     if inplen >= need:
          364         if have:
          365             for i in range(need):
          366                 ctx.buffer[have+i] = inp[i]
          367             RMD160Transform(ctx.state, ctx.buffer)
          368             off = need
          369             have = 0
          370         while off + 64 <= inplen:
          371             RMD160Transform(ctx.state, inp[off:]) #<---
          372             off += 64
          373     if off < inplen:
          374         # memcpy(ctx->buffer + have, input+off, len-off);
          375         for i in range(inplen - off):
          376             ctx.buffer[have+i] = inp[off+i]
          377 
          378 def RMD160Final(ctx):
          379     size = struct.pack("<Q", ctx.count)
          380     padlen = 64 - ((ctx.count // 8) % 64)
          381     if padlen < 1+8:
          382         padlen += 64
          383     RMD160Update(ctx, PADDING, padlen-8)
          384     RMD160Update(ctx, size, 8)
          385     return struct.pack("<5L", *ctx.state)
          386 
          387 
          388 assert '37f332f68db77bd9d7edd4969571ad671cf9dd3b' == \
          389        new(b'The quick brown fox jumps over the lazy dog').hexdigest()
          390 assert '132072df690933835eb8b6ad0b77e7b6f14acad7' == \
          391        new(b'The quick brown fox jumps over the lazy cog').hexdigest()
          392 assert '9c1185a5c5e9fc54612808977ee8f548b2258d31' == \
          393        new('').hexdigest()