deep-c-rsc/JCGO/jtrsrc/com/ivmaisoft/jcgo/SecHashAlg.java
2021-07-16 17:12:20 -05:00

220 lines
6.3 KiB
Java

/*
* @(#) $(JCGO)/jtrsrc/com/ivmaisoft/jcgo/SecHashAlg.java --
* a part of JCGO translator.
**
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
* Copyright (C) 2001-2012 Ivan Maidanski <ivmai@mail.ru>
* All rights reserved.
*/
/*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
**
* This software is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License (GPL) for more details.
**
* Linking this library statically or dynamically with other modules is
* making a combined work based on this library. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
**
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce an
* executable, regardless of the license terms of these independent
* modules, and to copy and distribute the resulting executable under
* terms of your choice, provided that you also meet, for each linked
* independent module, the terms and conditions of the license of that
* module. An independent module is a module which is not derived from
* or based on this library. If you modify this library, you may extend
* this exception to your version of the library, but you are not
* obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
package com.ivmaisoft.jcgo;
/**
* This class implements the Secure Hash Algorithm (SHA).
*/
final class SecHashAlg {
private int count;
private int aa;
private int bb;
private int cc;
private int dd;
private int ee;
private final int[] w = new int[80];
SecHashAlg() {
init();
}
void init() {
aa = 0x67452301;
bb = 0xefcdab89;
cc = 0x98badcfe;
dd = 0x10325476;
ee = 0xc3d2e1f0;
for (int i = 0; i < 80; i++) {
w[i] = 0;
}
count = 0;
}
private void computeBlock() {
for (int t = 16; t < 80; t++) {
int v = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
w[t] = (v << 1) | (v >>> 31);
}
int a = aa;
int b = bb;
int c = cc;
int d = dd;
int e = ee;
for (int i = 0; i < 20; i++) {
int v = ((a << 5) | (a >>> 27)) + ((b & c) | (~b & d)) + e + w[i]
+ 0x5a827999;
e = d;
d = c;
c = (b << 30) | (b >>> 2);
b = a;
a = v;
}
for (int i = 20; i < 40; i++) {
int v = ((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + w[i]
+ 0x6ed9eba1;
e = d;
d = c;
c = (b << 30) | (b >>> 2);
b = a;
a = v;
}
for (int i = 40; i < 60; i++) {
int v = ((a << 5) | (a >>> 27)) + ((b & c) | (b & d) | (c & d)) + e
+ w[i] + 0x8f1bbcdc;
e = d;
d = c;
c = (b << 30) | (b >>> 2);
b = a;
a = v;
}
for (int i = 60; i < 80; i++) {
int v = ((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + w[i]
+ 0xca62c1d6;
e = d;
d = c;
c = (b << 30) | (b >>> 2);
b = a;
a = v;
}
aa += a;
bb += b;
cc += c;
dd += d;
ee += e;
}
void engineUpdate(int b) {
int word = (count & 0x3f) >>> 2;
int offset = (~count & 0x3) << 3;
w[word] = (w[word] & ~(0xff << offset)) | ((b & 0xff) << offset);
if ((count & 0x3f) == 0x3f) {
computeBlock();
}
count++;
}
void updateInt(int v) {
engineUpdate(v >> 24);
engineUpdate(v >> 16);
engineUpdate(v >> 8);
engineUpdate(v);
}
void updateUTF(String str) {
int len = getUTFlength(str);
engineUpdate(len >> 8);
engineUpdate(len);
len = str.length();
for (int i = 0; i < len; i++) {
char ch = str.charAt(i);
if (ch == 0 || ch > 0x7f) {
if (ch > 0x7ff) {
engineUpdate((ch >> 12) | 0xe0);
engineUpdate(((ch >> 6) & 0x3f) | 0x80);
} else {
engineUpdate((ch >> 6) | 0xc0);
}
ch = (char) ((ch & 0x3f) | 0x80);
}
engineUpdate(ch);
}
}
private static int getUTFlength(String str) {
int len = str.length();
int utfLen = len;
for (int i = 0; i < len; i++) {
char ch = str.charAt(i);
if (ch == 0 || ch > 0x7f) {
utfLen++;
if (ch > 0x7ff) {
utfLen++;
}
}
}
return utfLen;
}
void finishUpdate() {
int bits = count << 3;
engineUpdate(0x80);
while ((count & 0x3f) != 0x38) {
engineUpdate(0);
}
w[14] = 0;
w[15] = bits;
count += 8;
computeBlock();
}
int engineDigestVal(byte[] hashvalue) {
if (hashvalue != null) {
hashvalue[0] = (byte) (aa >>> 24);
hashvalue[1] = (byte) (aa >> 16);
hashvalue[2] = (byte) (aa >> 8);
hashvalue[3] = (byte) aa;
hashvalue[4] = (byte) (bb >>> 24);
hashvalue[5] = (byte) (bb >> 16);
hashvalue[6] = (byte) (bb >> 8);
hashvalue[7] = (byte) bb;
hashvalue[8] = (byte) (cc >>> 24);
hashvalue[9] = (byte) (cc >> 16);
hashvalue[10] = (byte) (cc >> 8);
hashvalue[11] = (byte) cc;
hashvalue[12] = (byte) (dd >>> 24);
hashvalue[13] = (byte) (dd >> 16);
hashvalue[14] = (byte) (dd >> 8);
hashvalue[15] = (byte) dd;
hashvalue[16] = (byte) (ee >>> 24);
hashvalue[17] = (byte) (ee >> 16);
hashvalue[18] = (byte) (ee >> 8);
hashvalue[19] = (byte) ee;
}
return aa;
}
}