--- /dev/null	Tue Feb 19 01:00:50 2013
+++ new/usr/src/common/crypto/edonr/edonr.c	Tue Feb 19 01:00:50 2013
@@ -0,0 +1,744 @@
+/*
+ * IDI,NTNU
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright (C) 2009, 2010, Jorn Amundsen <jorn.amundsen@ntnu.no>
+ *
+ * Tweaked Edon-R implementation for SUPERCOP, based on NIST API.
+ *
+ * $Id: edonr.c 517 2013-02-17 20:34:39Z joern $
+ */
+/*
+ * Portions copyright (c) 2013, Saso Kiselkov, All rights reserved
+ */
+
+#include <sys/edonr.h>
+
+/* for memcpy() */
+#include <sys/systm.h>
+
+/* big endian support, provides no-op's if run on little endian hosts */
+#include "edonr_byteorder.h"
+
+#define	hashState224(x)	((x)->pipe->p256)
+#define	hashState256(x)	((x)->pipe->p256)
+#define	hashState384(x)	((x)->pipe->p512)
+#define	hashState512(x)	((x)->pipe->p512)
+
+/* shift and rotate shortcuts */
+#define	shl(x, n)	((x) << n)
+#define	shr(x, n)	((x) >> n)
+
+#define	rotl32(x, n)	(((x) << (n)) | ((x) >> (32 - (n))))
+#define	rotr32(x, n)	(((x) >> (n)) | ((x) << (32 - (n))))
+
+#define	rotl64(x, n)	(((x) << (n)) | ((x) >> (64 - (n))))
+#define	rotr64(x, n)	(((x) >> (n)) | ((x) << (64 - (n))))
+
+#if !defined(__C99_RESTRICT)
+#define	restrict	/* restrict */
+#endif
+
+/* EdonR224 initial double chaining pipe */
+static const uint32_t i224p2[16] = {
+	0x00010203ul, 0x04050607ul, 0x08090a0bul, 0x0c0d0e0ful,
+	0x10111213ul, 0x14151617ul, 0x18191a1bul, 0x1c1d1e1ful,
+	0x20212223ul, 0x24252627ul, 0x28292a2bul, 0x2c2d2e2ful,
+	0x30313233ul, 0x34353637ul, 0x38393a3bul, 0x3c3d3e3ful,
+};
+
+/* EdonR256 initial double chaining pipe */
+static const uint32_t i256p2[16] = {
+	0x40414243ul, 0x44454647ul, 0x48494a4bul, 0x4c4d4e4ful,
+	0x50515253ul, 0x54555657ul, 0x58595a5bul, 0x5c5d5e5ful,
+	0x60616263ul, 0x64656667ul, 0x68696a6bul, 0x6c6d6e6ful,
+	0x70717273ul, 0x74757677ul, 0x78797a7bul, 0x7c7d7e7ful,
+};
+
+/* EdonR384 initial double chaining pipe */
+static const uint64_t i384p2[16] = {
+	0x0001020304050607ull, 0x08090a0b0c0d0e0full,
+	0x1011121314151617ull, 0x18191a1b1c1d1e1full,
+	0x2021222324252627ull, 0x28292a2b2c2d2e2full,
+	0x3031323334353637ull, 0x38393a3b3c3d3e3full,
+	0x4041424344454647ull, 0x48494a4b4c4d4e4full,
+	0x5051525354555657ull, 0x58595a5b5c5d5e5full,
+	0x6061626364656667ull, 0x68696a6b6c6d6e6full,
+	0x7071727374757677ull, 0x78797a7b7c7d7e7full
+};
+
+/* EdonR512 initial double chaining pipe */
+static const uint64_t i512p2[16] = {
+	0x8081828384858687ull, 0x88898a8b8c8d8e8full,
+	0x9091929394959697ull, 0x98999a9b9c9d9e9full,
+	0xa0a1a2a3a4a5a6a7ull, 0xa8a9aaabacadaeafull,
+	0xb0b1b2b3b4b5b6b7ull, 0xb8b9babbbcbdbebfull,
+	0xc0c1c2c3c4c5c6c7ull, 0xc8c9cacbcccdcecfull,
+	0xd0d1d2d3d4d5d6d7ull, 0xd8d9dadbdcdddedfull,
+	0xe0e1e2e3e4e5e6e7ull, 0xe8e9eaebecedeeefull,
+	0xf0f1f2f3f4f5f6f7ull, 0xf8f9fafbfcfdfeffull
+};
+
+/*
+ * First Latin Square
+ * 0   7   1   3   2   4   6   5
+ * 4   1   7   6   3   0   5   2
+ * 7   0   4   2   5   3   1   6
+ * 1   4   0   5   6   2   7   3
+ * 2   3   6   7   1   5   0   4
+ * 5   2   3   1   7   6   4   0
+ * 3   6   5   0   4   7   2   1
+ * 6   5   2   4   0   1   3   7
+ */
+#define	LS1_256(c, x0, x1, x2, x3, x4, x5, x6, x7)\
+{\
+	uint32_t x04, x17, x23, x56, x07, x26;\
+\
+	x04 = x0+x4, x17 = x1+x7, x07 = x04+x17;\
+	s0 = c    + x07 + x2;\
+	s1 = rotl32(x07 + x3, 4);\
+	s2 = rotl32(x07 + x6, 8);\
+	x23 = x2 + x3;\
+	s5 = rotl32(x04 + x23 + x5, 22);\
+	x56 = x5 + x6;\
+	s6 = rotl32(x17 + x56 + x0, 24);\
+	x26 = x23+x56;\
+	s3 = rotl32(x26 + x7, 13);\
+	s4 = rotl32(x26 + x1, 17);\
+	s7 = rotl32(x26 + x4, 29);\
+}
+
+#define	LS1_512(c, x0, x1, x2, x3, x4, x5, x6, x7)\
+{\
+	uint64_t x04, x17, x23, x56, x07, x26;\
+\
+	x04 = x0+x4, x17 = x1+x7, x07 = x04+x17;\
+	s0 = c    + x07 + x2;\
+	s1 = rotl64(x07 + x3, 5);\
+	s2 = rotl64(x07 + x6, 15);\
+	x23 = x2 + x3;\
+	s5 = rotl64(x04 + x23 + x5, 40);\
+	x56 = x5 + x6;\
+	s6 = rotl64(x17 + x56 + x0, 50);\
+	x26 = x23+x56;\
+	s3 = rotl64(x26 + x7, 22);\
+	s4 = rotl64(x26 + x1, 31);\
+	s7 = rotl64(x26 + x4, 59);\
+}
+
+/*
+ * Second Orthogonal Latin Square
+ * 0   4   2   3   1   6   5   7
+ * 7   6   3   2   5   4   1   0
+ * 5   3   1   6   0   2   7   4
+ * 1   0   5   4   3   7   2   6
+ * 2   1   0   7   4   5   6   3
+ * 3   5   7   0   6   1   4   2
+ * 4   7   6   1   2   0   3   5
+ * 6   2   4   5   7   3   0   1
+ */
+#define	LS2_256(c, y0, y1, y2, y3, y4, y5, y6, y7)\
+{\
+	uint32_t y01, y25, y34, y67, y04, y05, y27, y37;\
+\
+	y01 = y0+y1, y25 = y2+y5, y05 = y01+y25;\
+	t0  = ~c  + y05 + y7;\
+	t2 = rotl32(y05 + y3, 9);\
+	y34 = y3+y4, y04 = y01+y34;\
+	t1 = rotl32(y04 + y6, 5);\
+	t4 = rotl32(y04 + y5, 15);\
+	y67 = y6+y7, y37 = y34+y67;\
+	t3 = rotl32(y37 + y2, 11);\
+	t7 = rotl32(y37 + y0, 27);\
+	y27 = y25+y67;\
+	t5 = rotl32(y27 + y4, 20);\
+	t6 = rotl32(y27 + y1, 25);\
+}
+
+#define	LS2_512(c, y0, y1, y2, y3, y4, y5, y6, y7)\
+{\
+	uint64_t y01, y25, y34, y67, y04, y05, y27, y37;\
+\
+	y01 = y0+y1, y25 = y2+y5, y05 = y01+y25;\
+	t0  = ~c  + y05 + y7;\
+	t2 = rotl64(y05 + y3, 19);\
+	y34 = y3+y4, y04 = y01+y34;\
+	t1 = rotl64(y04 + y6, 10);\
+	t4 = rotl64(y04 + y5, 36);\
+	y67 = y6+y7, y37 = y34+y67;\
+	t3 = rotl64(y37 + y2, 29);\
+	t7 = rotl64(y37 + y0, 55);\
+	y27 = y25+y67;\
+	t5 = rotl64(y27 + y4, 44);\
+	t6 = rotl64(y27 + y1, 48);\
+}
+
+#define	quasi_exform256(r0, r1, r2, r3, r4, r5, r6, r7)\
+{\
+	uint32_t s04, s17, s23, s56, t01, t25, t34, t67;\
+\
+	s04 = s0 ^ s4, t01 = t0 ^ t1;\
+	r0 = (s04 ^ s1) + (t01 ^ t5);\
+	t67 = t6 ^ t7;\
+	r1 = (s04 ^ s7) + (t2 ^ t67);\
+	s23 = s2 ^ s3;\
+	r7 = (s23 ^ s5) + (t4 ^ t67);\
+	t34 = t3 ^ t4;\
+	r3 = (s23 ^ s4) + (t0 ^ t34);\
+	s56 = s5 ^ s6;\
+	r5 = (s3 ^ s56) + (t34 ^ t6);\
+	t25 = t2 ^ t5;\
+	r6 = (s2 ^ s56) + (t25 ^ t7);\
+	s17 = s1 ^ s7;\
+	r4 = (s0 ^ s17) + (t1 ^ t25);\
+	r2 = (s17 ^ s6) + (t01 ^ t3);\
+}
+
+#define	quasi_exform512(r0, r1, r2, r3, r4, r5, r6, r7)\
+{\
+	uint64_t s04, s17, s23, s56, t01, t25, t34, t67;\
+\
+	s04 = s0 ^ s4, t01 = t0 ^ t1;\
+	r0 = (s04 ^ s1) + (t01 ^ t5);\
+	t67 = t6 ^ t7;\
+	r1 = (s04 ^ s7) + (t2 ^ t67);\
+	s23 = s2 ^ s3;\
+	r7 = (s23 ^ s5) + (t4 ^ t67);\
+	t34 = t3 ^ t4;\
+	r3 = (s23 ^ s4) + (t0 ^ t34);\
+	s56 = s5 ^ s6;\
+	r5 = (s3 ^ s56) + (t34 ^ t6);\
+	t25 = t2 ^ t5;\
+	r6 = (s2 ^ s56) + (t25 ^ t7);\
+	s17 = s1 ^ s7;\
+	r4 = (s0 ^ s17) + (t1 ^ t25);\
+	r2 = (s17 ^ s6) + (t01 ^ t3);\
+}
+
+static size_t
+Q256(size_t bitlen, const uint32_t *data, uint32_t *restrict p)
+{
+	size_t bl;
+
+	for (bl = bitlen; bl >= EdonR256_BLOCK_BITSIZE;
+	    bl -= EdonR256_BLOCK_BITSIZE, data += 16) {
+		uint32_t s0, s1, s2, s3, s4, s5, s6, s7, t0, t1, t2, t3, t4,
+		    t5, t6, t7;
+		uint32_t p0, p1, p2, p3, p4, p5, p6, p7, q0, q1, q2, q3, q4,
+		    q5, q6, q7;
+		const uint32_t defix = 0xaaaaaaaa;
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		uint32_t swp0, swp1, swp2, swp3, swp4, swp5, swp6, swp7, swp8,
+		    swp9, swp10, swp11, swp12, swp13, swp14, swp15;
+#define	d(j)	swp##j
+#define	s32(j)	ld_swap32((uint32_t *)data+j, swp##j)
+#else
+#define	d(j)	data[j]
+#endif
+
+		/* First row of quasigroup e-transformations */
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		s32(8);
+		s32(9);
+		s32(10);
+		s32(11);
+		s32(12);
+		s32(13);
+		s32(14);
+		s32(15);
+#endif
+		LS1_256(defix, d(15), d(14), d(13), d(12), d(11), d(10), d(9),
+		    d(8));
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		s32(0);
+		s32(1);
+		s32(2);
+		s32(3);
+		s32(4);
+		s32(5);
+		s32(6);
+		s32(7);
+#undef s32
+#endif
+		LS2_256(defix, d(0), d(1), d(2), d(3), d(4), d(5), d(6), d(7));
+		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_256(defix, d(8), d(9), d(10), d(11), d(12), d(13), d(14),
+		    d(15));
+		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Second row of quasigroup e-transformations */
+		LS1_256(defix, p[8], p[9], p[10], p[11], p[12], p[13], p[14],
+		    p[15]);
+		LS2_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_256(defix, q0, q1, q2, q3, q4, q5, q6, q7);
+		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Third row of quasigroup e-transformations */
+		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_256(defix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_256(defix, q0, q1, q2, q3, q4, q5, q6, q7);
+		LS2_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Fourth row of quasigroup e-transformations */
+		LS1_256(defix, d(7), d(6), d(5), d(4), d(3), d(2), d(1), d(0));
+		LS2_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		quasi_exform256(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_256(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_256(defix, q0, q1, q2, q3, q4, q5, q6, q7);
+		quasi_exform256(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Edon-R tweak on the original SHA-3 Edon-R submission. */
+		p[0] ^= d(8) ^ p0;
+		p[1] ^= d(9) ^ p1;
+		p[2] ^= d(10) ^ p2;
+		p[3] ^= d(11) ^ p3;
+		p[4] ^= d(12) ^ p4;
+		p[5] ^= d(13) ^ p5;
+		p[6] ^= d(14) ^ p6;
+		p[7] ^= d(15) ^ p7;
+		p[8] ^= d(0) ^ q0;
+		p[9] ^= d(1) ^ q1;
+		p[10] ^= d(2) ^ q2;
+		p[11] ^= d(3) ^ q3;
+		p[12] ^= d(4) ^ q4;
+		p[13] ^= d(5) ^ q5;
+		p[14] ^= d(6) ^ q6;
+		p[15] ^= d(7) ^ q7;
+	}
+
+#undef d
+	return (bitlen - bl);
+}
+
+#if defined(__IBMC__) && defined(_AIX) && defined(__64BIT__)
+static inline size_t
+#else
+static size_t
+#endif
+Q512(size_t bitlen, const uint64_t *data, uint64_t *restrict p)
+{
+	size_t bl;
+
+	for (bl = bitlen; bl >= EdonR512_BLOCK_BITSIZE;
+	    bl -= EdonR512_BLOCK_BITSIZE, data += 16) {
+		uint64_t s0, s1, s2, s3, s4, s5, s6, s7, t0, t1, t2, t3, t4,
+		    t5, t6, t7;
+		uint64_t p0, p1, p2, p3, p4, p5, p6, p7, q0, q1, q2, q3, q4,
+		    q5, q6, q7;
+		const uint64_t defix = 0xaaaaaaaaaaaaaaaaull;
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		uint64_t swp0, swp1, swp2, swp3, swp4, swp5, swp6, swp7, swp8,
+		    swp9, swp10, swp11, swp12, swp13, swp14, swp15;
+#define	d(j)	swp##j
+#define	s64(j)	ld_swap64((uint64_t *)data+j, swp##j)
+#else
+#define	d(j)	data[j]
+#endif
+
+		/* First row of quasigroup e-transformations */
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		s64(8);
+		s64(9);
+		s64(10);
+		s64(11);
+		s64(12);
+		s64(13);
+		s64(14);
+		s64(15);
+#endif
+		LS1_512(defix, d(15), d(14), d(13), d(12), d(11), d(10), d(9),
+		    d(8));
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		s64(0);
+		s64(1);
+		s64(2);
+		s64(3);
+		s64(4);
+		s64(5);
+		s64(6);
+		s64(7);
+#undef s64
+#endif
+		LS2_512(defix, d(0), d(1), d(2), d(3), d(4), d(5), d(6), d(7));
+		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_512(defix, d(8), d(9), d(10), d(11), d(12), d(13), d(14),
+		    d(15));
+		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Second row of quasigroup e-transformations */
+		LS1_512(defix, p[8], p[9], p[10], p[11], p[12], p[13], p[14],
+		    p[15]);
+		LS2_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_512(defix, q0, q1, q2, q3, q4, q5, q6, q7);
+		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Third row of quasigroup e-transformations */
+		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_512(defix, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_512(defix, q0, q1, q2, q3, q4, q5, q6, q7);
+		LS2_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Fourth row of quasigroup e-transformations */
+		LS1_512(defix, d(7), d(6), d(5), d(4), d(3), d(2), d(1), d(0));
+		LS2_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		quasi_exform512(p0, p1, p2, p3, p4, p5, p6, p7);
+
+		LS1_512(defix, p0, p1, p2, p3, p4, p5, p6, p7);
+		LS2_512(defix, q0, q1, q2, q3, q4, q5, q6, q7);
+		quasi_exform512(q0, q1, q2, q3, q4, q5, q6, q7);
+
+		/* Edon-R tweak on the original SHA-3 Edon-R submission. */
+		p[0] ^= d(8) ^ p0;
+		p[1] ^= d(9) ^ p1;
+		p[2] ^= d(10) ^ p2;
+		p[3] ^= d(11) ^ p3;
+		p[4] ^= d(12) ^ p4;
+		p[5] ^= d(13) ^ p5;
+		p[6] ^= d(14) ^ p6;
+		p[7] ^= d(15) ^ p7;
+		p[8] ^= d(0) ^ q0;
+		p[9] ^= d(1) ^ q1;
+		p[10] ^= d(2) ^ q2;
+		p[11] ^= d(3) ^ q3;
+		p[12] ^= d(4) ^ q4;
+		p[13] ^= d(5) ^ q5;
+		p[14] ^= d(6) ^ q6;
+		p[15] ^= d(7) ^ q7;
+	}
+
+#undef d
+	return (bitlen - bl);
+}
+
+void
+EdonRInit(EdonRState *state, size_t hashbitlen)
+{
+	switch (hashbitlen) {
+	case 224:
+		state->hashbitlen = 224;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		(void) memcpy(hashState224(state)->DoublePipe, i224p2,
+		    16 * sizeof (uint32_t));
+		break;
+
+	case 256:
+		state->hashbitlen = 256;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		(void) memcpy(hashState256(state)->DoublePipe, i256p2,
+		    16 * sizeof (uint32_t));
+		break;
+
+	case 384:
+		state->hashbitlen = 384;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		(void) memcpy(hashState384(state)->DoublePipe, i384p2,
+		    16 * sizeof (uint64_t));
+		break;
+
+	case 512:
+		state->hashbitlen = 512;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		(void) memcpy(hashState224(state)->DoublePipe, i512p2,
+		    16 * sizeof (uint64_t));
+		break;
+
+	default:
+		ASSERT(0);
+	}
+}
+
+
+void
+EdonRUpdate(EdonRState *state, const uint8_t *data, size_t databitlen)
+{
+	uint32_t *data32;
+	uint64_t *data64;
+
+	size_t bits_processed;
+
+	switch (state->hashbitlen) {
+	case 224:
+	case 256:
+		if (state->unprocessed_bits > 0) {
+			ASSERT(state->unprocessed_bits + databitlen <=
+			    EdonR256_BLOCK_SIZE * 8);
+
+			/* LastBytes = databitlen / 8 */
+			int LastBytes = (int) databitlen >> 3;
+
+			(void) memcpy(hashState256(state)->LastPart
+			    + (state->unprocessed_bits >> 3), data,
+			    LastBytes);
+			state->unprocessed_bits += (int) databitlen;
+			databitlen = state->unprocessed_bits;
+			/* LINTED E_BAD_PTR_CAST_ALIGN */
+			data32 = (uint32_t *) hashState256(state)->LastPart;
+		} else
+			/* LINTED E_BAD_PTR_CAST_ALIGN */
+			data32 = (uint32_t *) data;
+
+		bits_processed = Q256(databitlen, data32,
+		    hashState256(state)->DoublePipe);
+		state->bits_processed += bits_processed;
+		databitlen -= bits_processed;
+		state->unprocessed_bits = (int) databitlen;
+		if (databitlen > 0) {
+			/* LastBytes = Ceil(databitlen / 8) */
+			int LastBytes =
+			    ((~(((-(int) databitlen) >> 3) & 0x01ff)) +
+			    1) & 0x01ff;
+
+			data32 += bits_processed >> 5;	/* byte size update */
+			(void) memcpy(hashState256(state)->LastPart, data32,
+			    LastBytes);
+		}
+		break;
+
+	case 384:
+	case 512:
+		if (state->unprocessed_bits > 0) {
+			ASSERT(state->unprocessed_bits + databitlen <=
+			    EdonR512_BLOCK_SIZE * 8);
+			/* LastBytes = databitlen / 8 */
+			int LastBytes = (int) databitlen >> 3;
+
+			(void) memcpy(hashState512(state)->LastPart
+			    + (state->unprocessed_bits >> 3), data,
+			    LastBytes);
+			state->unprocessed_bits += (int) databitlen;
+			databitlen = state->unprocessed_bits;
+			/* LINTED E_BAD_PTR_CAST_ALIGN */
+			data64 = (uint64_t *) hashState512(state)->LastPart;
+		} else
+			/* LINTED E_BAD_PTR_CAST_ALIGN */
+			data64 = (uint64_t *) data;
+
+
+		bits_processed = Q512(databitlen, data64,
+		    hashState512(state)->DoublePipe);
+		state->bits_processed += bits_processed;
+		databitlen -= bits_processed;
+		state->unprocessed_bits = (int) databitlen;
+		if (databitlen > 0) {
+			/* LastBytes = Ceil(databitlen / 8) */
+			int LastBytes =
+			    ((~(((-(int) databitlen) >> 3) & 0x03ff)) +
+			    1) & 0x03ff;
+
+			data64 += bits_processed >> 6;	/* byte size update */
+			(void) memcpy(hashState512(state)->LastPart, data64,
+			    LastBytes);
+		}
+		break;
+
+	default:
+		ASSERT(0);
+	}
+}
+
+void
+EdonRFinal(EdonRState *state, uint8_t *hashval)
+{
+	uint32_t *data32;
+	uint64_t *data64, num_bits;
+
+	size_t databitlen;
+	int LastByte, PadOnePosition;
+
+	num_bits = state->bits_processed + state->unprocessed_bits;
+
+	switch (state->hashbitlen) {
+	case 224:
+	case 256:
+		LastByte = (int) state->unprocessed_bits >> 3;
+		PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
+		hashState256(state)->LastPart[LastByte] =
+		    (hashState256(state)->LastPart[LastByte]
+		    & (0xff << (PadOnePosition +
+			    1))) ^ (0x01 << PadOnePosition);
+		/* LINTED E_BAD_PTR_CAST_ALIGN */
+		data64 = (uint64_t *) hashState256(state)->LastPart;
+
+		if (state->unprocessed_bits < 448) {
+			(void) memset((hashState256(state)->LastPart) +
+			    LastByte + 1, 0x00,
+			    EdonR256_BLOCK_SIZE - LastByte - 9);
+			databitlen = EdonR256_BLOCK_SIZE * 8;
+#if defined(MACHINE_IS_BIG_ENDIAN)
+			st_swap64(num_bits, data64 + 7);
+#else
+			data64[7] = num_bits;
+#endif
+		} else {
+			(void) memset((hashState256(state)->LastPart) +
+			    LastByte + 1, 0x00,
+			    EdonR256_BLOCK_SIZE * 2 - LastByte - 9);
+			databitlen = EdonR256_BLOCK_SIZE * 16;
+#if defined(MACHINE_IS_BIG_ENDIAN)
+			st_swap64(num_bits, data64 + 15);
+#else
+			data64[15] = num_bits;
+#endif
+		}
+
+		/* LINTED E_BAD_PTR_CAST_ALIGN */
+		data32 = (uint32_t *) hashState256(state)->LastPart;
+		state->bits_processed += Q256(databitlen, data32,
+		    hashState256(state)->DoublePipe);
+		break;
+
+	case 384:
+	case 512:
+		LastByte = (int) state->unprocessed_bits >> 3;
+		PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
+		hashState512(state)->LastPart[LastByte] =
+		    (hashState512(state)->LastPart[LastByte]
+		    & (0xff << (PadOnePosition +
+			    1))) ^ (0x01 << PadOnePosition);
+		/* LINTED E_BAD_PTR_CAST_ALIGN */
+		data64 = (uint64_t *) hashState512(state)->LastPart;
+
+		if (state->unprocessed_bits < 960) {
+			(void) memset((hashState512(state)->LastPart) +
+			    LastByte + 1, 0x00,
+			    EdonR512_BLOCK_SIZE - LastByte - 9);
+			databitlen = EdonR512_BLOCK_SIZE * 8;
+#if defined(MACHINE_IS_BIG_ENDIAN)
+			st_swap64(num_bits, data64 + 15);
+#else
+			data64[15] = num_bits;
+#endif
+		} else {
+			(void) memset((hashState512(state)->LastPart) +
+			    LastByte + 1, 0x00,
+			    EdonR512_BLOCK_SIZE * 2 - LastByte - 9);
+			databitlen = EdonR512_BLOCK_SIZE * 16;
+#if defined(MACHINE_IS_BIG_ENDIAN)
+			st_swap64(num_bits, data64 + 31);
+#else
+			data64[31] = num_bits;
+#endif
+		}
+
+		state->bits_processed += Q512(databitlen, data64,
+		    hashState512(state)->DoublePipe);
+		break;
+
+	default:
+		ASSERT(0);	/* This should never happen */
+	}
+
+
+	switch (state->hashbitlen) {
+	case 224: {
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		uint32_t *d32 = (uint32_t *) hashval;
+		uint32_t *s32 = hashState224(state)->DoublePipe + 9;
+		int j;
+
+		for (j = 0; j < EdonR224_DIGEST_SIZE >> 2; j++)
+			st_swap32(s32[j], d32 + j);
+#else
+		(void) memcpy(hashval, hashState256(state)->DoublePipe + 9,
+		    EdonR224_DIGEST_SIZE);
+#endif
+		break;
+	}
+	case 256: {
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		uint32_t *d32 = (uint32_t *) hashval;
+		uint32_t *s32 = hashState224(state)->DoublePipe + 8;
+		int j;
+
+		for (j = 0; j < EdonR256_DIGEST_SIZE >> 2; j++)
+			st_swap32(s32[j], d32 + j);
+#else
+		(void) memcpy(hashval, hashState256(state)->DoublePipe + 8,
+		    EdonR256_DIGEST_SIZE);
+#endif
+		break;
+	}
+	case 384: {
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		uint64_t *d64 = (uint64_t *) hashval;
+		uint64_t *s64 = hashState384(state)->DoublePipe + 10;
+		int j;
+
+		for (j = 0; j < EdonR384_DIGEST_SIZE >> 3; j++)
+			st_swap64(s64[j], d64 + j);
+#else
+		(void) memcpy(hashval, hashState384(state)->DoublePipe + 10,
+		    EdonR384_DIGEST_SIZE);
+#endif
+		break;
+	}
+	case 512: {
+#if defined(MACHINE_IS_BIG_ENDIAN)
+		uint64_t *d64 = (uint64_t *) hashval;
+		uint64_t *s64 = hashState512(state)->DoublePipe + 8;
+		int j;
+
+		for (j = 0; j < EdonR512_DIGEST_SIZE >> 3; j++)
+			st_swap64(s64[j], d64 + j);
+#else
+		(void) memcpy(hashval, hashState512(state)->DoublePipe + 8,
+		    EdonR512_DIGEST_SIZE);
+#endif
+		break;
+	}
+
+	default:
+		ASSERT(0);	/* This should never happen */
+	}
+}
+
+
+void
+EdonRHash(size_t hashbitlen, const uint8_t *data, size_t databitlen,
+    uint8_t *hashval)
+{
+	EdonRState state;
+
+	EdonRInit(&state, hashbitlen);
+	EdonRUpdate(&state, data, databitlen);
+	EdonRFinal(&state, hashval);
+}
--- /dev/null	Tue Feb 19 01:00:50 2013
+++ new/usr/src/common/crypto/edonr/edonr_byteorder.h	Tue Feb 19 01:00:50 2013
@@ -0,0 +1,222 @@
+/*
+ * IDI,NTNU
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright (C) 2009, 2010, Jorn Amundsen <jorn.amundsen@ntnu.no>
+ *
+ * C header file to determine compile machine byte order. Take care when cross
+ * compiling.
+ *
+ * $Id: byteorder.h 517 2013-02-17 20:34:39Z joern $
+ */
+/*
+ * Portions copyright (c) 2013, Saso Kiselkov, All rights reserved
+ */
+
+#if !defined(BYTEORDER_INCLUDED)
+
+#if defined(__linux)
+#include <endian.h>
+#else
+#include <sys/param.h>
+#endif
+
+#if defined(__BYTE_ORDER)
+#if (__BYTE_ORDER == __BIG_ENDIAN)
+#define	MACHINE_IS_BIG_ENDIAN
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN)
+#define	MACHINE_IS_LITTLE_ENDIAN
+#endif
+#elif defined(BYTE_ORDER)
+#if (BYTE_ORDER == BIG_ENDIAN)
+#define	MACHINE_IS_BIG_ENDIAN
+#elif (BYTE_ORDER == LITTLE_ENDIAN)
+#define	MACHINE_IS_LITTLE_ENDIAN
+#endif
+#endif /* __BYTE_ORDER || BYTE_ORDER */
+
+#if !defined(MACHINE_IS_BIG_ENDIAN) && !defined(MACHINE_IS_LITTLE_ENDIAN)
+#if defined(_BIG_ENDIAN) || defined(_MIPSEB)
+#define	MACHINE_IS_BIG_ENDIAN
+#endif
+#if defined(_LITTLE_ENDIAN) || defined(_MIPSEL)
+#define	MACHINE_IS_LITTLE_ENDIAN
+#endif
+#endif /* !MACHINE_IS_BIG_ENDIAN && !MACHINE_IS_LITTLE_ENDIAN */
+
+#if !defined(MACHINE_IS_BIG_ENDIAN) && !defined(MACHINE_IS_LITTLE_ENDIAN)
+#error unknown machine byte sex
+#endif
+
+#define	BYTEORDER_INCLUDED
+
+#if defined(MACHINE_IS_BIG_ENDIAN)
+/*
+ * Byte swapping macros for big endian architectures and compilers,
+ * add as appropriate for other architectures and/or compilers.
+ *
+ *     ld_swap64(src,dst) : uint64_t dst = *(src)
+ *     st_swap64(src,dst) : *(dst)       = uint64_t src
+ */
+
+#if defined(__PPC__) || defined(_ARCH_PPC)
+
+#if defined(__64BIT__)
+#if defined(_ARCH_PWR7)
+#define	aix_ld_swap64(s64, d64)\
+	__asm__("ldbrx %0,0,%1" : "=r"(d64) : "r"(s64))
+#define	aix_st_swap64(s64, d64)\
+	__asm__ volatile("stdbrx %1,0,%0" : : "r"(d64), "r"(s64))
+#else
+#define	aix_ld_swap64(s64, d64)\
+{\
+	uint64_t *s4, h;\
+\
+	__asm__("addi %0,%3,4;lwbrx %1,0,%3;lwbrx %2,0,%0;rldimi %1,%2,32,0"\
+		: "+r"(s4), "=r"(d64), "=r"(h) : "b"(s64));\
+}
+
+#define	aix_st_swap64(s64, d64)\
+{\
+	uint64_t *s4, h;\
+\
+	h = (s64) >> 32;\
+\
+	__asm__ volatile("addi %0,%3,4;stwbrx %1,0,%3;stwbrx %2,0,%0"\
+		: "+r"(s4) : "r"(s64), "r"(h), "b"(d64));\
+}
+#endif /* 64BIT && PWR7 */
+#else
+#define	aix_ld_swap64(s64, d64)\
+{\
+	uint32_t *s4, h, l;\
+\
+	__asm__("addi %0,%3,4;lwbrx %1,0,%3;lwbrx %2,0,%0"\
+		: "+r"(s4), "=r"(l), "=r"(h) : "b"(s64));\
+\
+	d64 = ((uint64_t)h<<32) | l;\
+}
+
+#define	aix_st_swap64(s64, d64)\
+{\
+	uint32_t *s4, h, l;\
+\
+	l = (s64) & 0xfffffffful, h = (s64) >> 32;\
+\
+	__asm__ volatile("addi %0,%3,4;stwbrx %1,0,%3;stwbrx %2,0,%0"\
+		: "+r"(s4) : "r"(l), "r"(h), "b"(d64));\
+}
+#endif /* __64BIT__ */
+#define	aix_ld_swap32(s32, d32)\
+	__asm__("lwbrx %0,0,%1" : "=r"(d32) : "r"(s32))
+#define	aix_st_swap32(s32, d32)\
+	__asm__ volatile("stwbrx %1,0,%0" : : "r"(d32), "r"(s32))
+#define	ld_swap32(s, d) aix_ld_swap32(s, d)
+#define	st_swap32(s, d) aix_st_swap32(s, d)
+#define	ld_swap64(s, d) aix_ld_swap64(s, d)
+#define	st_swap64(s, d) aix_st_swap64(s, d)
+#endif /* __PPC__ || _ARCH_PPC */
+
+#if defined(__sparc)
+#if !defined(__arch64__) && !defined(__sparcv8) && defined(__sparcv9)
+#define	__arch64__
+#endif
+#if defined(__GNUC__) || (defined(__SUNPRO_C) && __SUNPRO_C > 0x590)
+/* need Sun Studio C 5.10 and above for GNU inline assembly */
+#if defined(__arch64__)
+#define	sparc_ld_swap64(s64, d64)\
+	__asm__("ldxa [%1]0x88,%0" : "=r"(d64) : "r"(s64))
+#define	sparc_st_swap64(s64, d64)\
+	__asm__ volatile("stxa %0,[%1]0x88" : : "r"(s64), "r"(d64))
+#define	st_swap64(s, d) sparc_st_swap64(s, d)
+#else
+#define	sparc_ld_swap64(s64, d64)\
+{\
+	uint32_t *s4, h, l;\
+\
+	__asm__("add %3,4,%0\n\tlda [%3]0x88,%1\n\tlda [%0]0x88,%2"\
+		: "+r"(s4), "=r"(l), "=r"(h) : "r"(s64));\
+\
+	d64 = ((uint64_t)h<<32) | l;\
+}
+#define	sparc_st_swap64(s64, d64)\
+{\
+	uint32_t *s4, h, l;\
+\
+	l = (s64) & 0xfffffffful, h = (s64) >> 32;\
+\
+	__asm__ volatile("add %3,4,%0\n\tsta %1,[%3]0x88\n\tsta %2,[%0]0x88"\
+		: "+r"(s4) : "r"(l), "r"(h), "r"(d64));\
+}
+#endif /* sparc64 */
+#define	sparc_ld_swap32(s32, d32)\
+	__asm__("lda [%1]0x88,%0" : "=r"(d32) : "r"(s32))
+#define	sparc_st_swap32(s32, d32)\
+	__asm__ volatile("sta %0,[%1]0x88" : : "r"(s32), "r"(d32))
+#define	ld_swap32(s, d) sparc_ld_swap32(s, d)
+#define	st_swap32(s, d) sparc_st_swap32(s, d)
+#define	ld_swap64(s, d) sparc_ld_swap64(s, d)
+#define	st_swap64(s, d) sparc_st_swap64(s, d)
+#endif /* GCC || Sun Studio C > 5.9 */
+#endif /* sparc */
+
+/* GCC fallback */
+#if ((__GNUC__ >= 4) || defined(__PGIC__)) && !defined(ld_swap32)
+#define	ld_swap32(s, d) (d = __builtin_bswap32(*(s)))
+#define	st_swap32(s, d) (*(d) = __builtin_bswap32(s))
+#endif /* GCC4/PGIC && !swap32 */
+#if ((__GNUC__ >= 4) || defined(__PGIC__)) && !defined(ld_swap64)
+#define	ld_swap64(s, d) (d = __builtin_bswap64(*(s)))
+#define	st_swap64(s, d) (*(d) = __builtin_bswap64(s))
+#endif /* GCC4/PGIC && !swap64 */
+
+/* generic fallback */
+#if !defined(ld_swap32)
+#define	ld_swap32(s, d) (d = \
+	(*(s)>>24)|(*(s)>>8&0xff00)|(*(s)<<8&0xff0000)|(*(s)<<24))
+#define	st_swap32(s, d) (*(d) = \
+	((s)>>24)|((s)>>8&0xff00)|((s)<<8&0xff0000)|((s)<<24))
+#endif
+#if !defined(ld_swap64)
+#define	ld_swap64(s, d) (d = (*(s)>>56)|(*(s)>>40&0xff00)|(*(s)>>24&0xff0000)|\
+	(*(s)>>8&0xff000000)|(*(s)&0xff000000)<<8|(*(s)&0xff0000)<<24|\
+	(*(s)&0xff00)<<40|*(s)<<56)
+#define	st_swap64(s, d) (*(d) = ((s)>>56)|((s)>>40&0xff00)|((s)>>24&0xff0000)|\
+	((s)>>8&0xff000000)|((s)&0xff000000)<<8|((s)&0xff0000)<<24|\
+	((s)&0xff00)<<40|(s)<<56)
+#endif
+
+#endif /* MACHINE_IS_BIG_ENDIAN */
+
+
+#if defined(MACHINE_IS_LITTLE_ENDIAN)
+/* replace swaps with simple assignments on little endian systems */
+#undef	ld_swap32
+#undef	st_swap32
+#define	ld_swap32(s, d) (d = *(s))
+#define	st_swap32(s, d) (*(d) = s)
+#undef	ld_swap64
+#undef	st_swap64
+#define	ld_swap64(s, d) (d = *(s))
+#define	st_swap64(s, d) (*(d) = s)
+#endif /* MACHINE_IS_LITTLE_ENDIAN */
+
+#endif /* BYTEORDER_INCLUDED */
--- old/usr/src/common/zfs/zfeature_common.c	Tue Feb 19 01:00:50 2013
+++ new/usr/src/common/zfs/zfeature_common.c	Tue Feb 19 01:00:50 2013
@@ -160,4 +160,8 @@
 	zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
 	    "org.illumos:lz4_compress", "lz4_compress",
 	    "LZ4 compression algorithm support.", B_FALSE, B_FALSE, NULL);
+	zfeature_register(SPA_FEATURE_EDONR_CKSUM,
+	    "org.illumos:edonr_cksum", "edonr_cksum",
+	    "Edon-R-512/256 checksum algorithm support.", B_FALSE, B_FALSE,
+	    NULL);
 }
--- old/usr/src/common/zfs/zfeature_common.h	Tue Feb 19 01:00:51 2013
+++ new/usr/src/common/zfs/zfeature_common.h	Tue Feb 19 01:00:51 2013
@@ -54,6 +54,7 @@
 	SPA_FEATURE_ASYNC_DESTROY,
 	SPA_FEATURE_EMPTY_BPOBJ,
 	SPA_FEATURE_LZ4_COMPRESS,
+	SPA_FEATURE_EDONR_CKSUM,
 	SPA_FEATURES
 } spa_feature_t;
 
--- old/usr/src/common/zfs/zfs_prop.c	Tue Feb 19 01:00:51 2013
+++ new/usr/src/common/zfs/zfs_prop.c	Tue Feb 19 01:00:51 2013
@@ -64,21 +64,25 @@
 zfs_prop_init(void)
 {
 	static zprop_index_t checksum_table[] = {
-		{ "on",		ZIO_CHECKSUM_ON },
-		{ "off",	ZIO_CHECKSUM_OFF },
-		{ "fletcher2",	ZIO_CHECKSUM_FLETCHER_2 },
-		{ "fletcher4",	ZIO_CHECKSUM_FLETCHER_4 },
-		{ "sha256",	ZIO_CHECKSUM_SHA256 },
+		{ "on",			ZIO_CHECKSUM_ON },
+		{ "off",		ZIO_CHECKSUM_OFF },
+		{ "fletcher2",		ZIO_CHECKSUM_FLETCHER_2 },
+		{ "fletcher4",		ZIO_CHECKSUM_FLETCHER_4 },
+		{ "sha256",		ZIO_CHECKSUM_SHA256 },
+		{ "edonr512/256",	ZIO_CHECKSUM_EDONR512_256 },
 		{ NULL }
 	};
 
 	static zprop_index_t dedup_table[] = {
-		{ "on",		ZIO_CHECKSUM_ON },
-		{ "off",	ZIO_CHECKSUM_OFF },
-		{ "verify",	ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY },
-		{ "sha256",	ZIO_CHECKSUM_SHA256 },
+		{ "on",			ZIO_CHECKSUM_ON },
+		{ "off",		ZIO_CHECKSUM_OFF },
+		{ "verify",		ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY },
+		{ "sha256",		ZIO_CHECKSUM_SHA256 },
 		{ "sha256,verify",
-				ZIO_CHECKSUM_SHA256 | ZIO_CHECKSUM_VERIFY },
+			ZIO_CHECKSUM_SHA256 | ZIO_CHECKSUM_VERIFY },
+		{ "edonr512/256",	ZIO_CHECKSUM_EDONR512_256 },
+		{ "edonr512/256,verify",
+			ZIO_CHECKSUM_EDONR512_256 | ZIO_CHECKSUM_VERIFY },
 		{ NULL }
 	};
 
@@ -204,12 +208,12 @@
 	zprop_register_index(ZFS_PROP_CHECKSUM, "checksum",
 	    ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM |
 	    ZFS_TYPE_VOLUME,
-	    "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM",
-	    checksum_table);
+	    "on | off | fletcher2 | fletcher4 | sha256 | edonr512/256",
+	    "CHECKSUM", checksum_table);
 	zprop_register_index(ZFS_PROP_DEDUP, "dedup", ZIO_CHECKSUM_OFF,
 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
-	    "on | off | verify | sha256[,verify]", "DEDUP",
-	    dedup_table);
+	    "on | off | verify | sha256[,verify] | edonr512/256[,verify]",
+	    "DEDUP", dedup_table);
 	zprop_register_index(ZFS_PROP_COMPRESSION, "compression",
 	    ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
--- old/usr/src/common/zfs/zpool_prop.c	Tue Feb 19 01:00:51 2013
+++ new/usr/src/common/zfs/zpool_prop.c	Tue Feb 19 01:00:51 2013
@@ -123,6 +123,8 @@
 	/* hidden properties */
 	zprop_register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING,
 	    PROP_READONLY, ZFS_TYPE_POOL, "NAME");
+	zprop_register_hidden(ZPOOL_PROP_DDT_SALT, "ddt_salt", PROP_TYPE_STRING,
+	    PROP_READONLY, ZFS_TYPE_POOL, "DDT_SALT");
 }
 
 /*
--- old/usr/src/grub/grub-0.97/stage2/Makefile.am	Tue Feb 19 01:00:51 2013
+++ new/usr/src/grub/grub-0.97/stage2/Makefile.am	Tue Feb 19 01:00:51 2013
@@ -20,8 +20,8 @@
 	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
 	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs.c fsys_ufs2.c \
 	fsys_zfs.c zfs_fletcher.c zfs_lzjb.c zfs_lz4.c zfs_sha256.c \
-	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
-	terminfo.c tparm.c graphics.c
+	zfs_edonr.c fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c \
+	stage2.c terminfo.c tparm.c graphics.c
 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
 	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
 	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
@@ -102,8 +102,8 @@
 	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
 	fsys_reiserfs.c fsys_ufs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c \
 	fsys_zfs.c zfs_fletcher.c zfs_lzjb.c zfs_lz4.c zfs_sha256.c \
-	gunzip.c hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c \
-	tparm.c graphics.c
+	zfs_edonr.c gunzip.c hercules.c md5.c serial.c smp-imps.c stage2.c \
+	terminfo.c tparm.c graphics.c
 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
@@ -197,7 +197,7 @@
 # For zfs_stage1_5 target.
 zfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
 	stage1_5.c fsys_zfs.c zfs_fletcher.c zfs_lzjb.c zfs_lz4.c \
-	zfs_sha256.c bios.c
+	zfs_sha256.c zfs_edonr.c bios.c
 zfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ZFS=1 \
 	-DNO_BLOCK_FILES=1
 zfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ZFS=1 \
--- old/usr/src/grub/grub-0.97/stage2/Makefile.solaris	Tue Feb 19 01:00:51 2013
+++ new/usr/src/grub/grub-0.97/stage2/Makefile.solaris	Tue Feb 19 01:00:51 2013
@@ -73,6 +73,7 @@
 		  libgrub_a-fsys_minix.o	\
 		  libgrub_a-fsys_reiserfs.o	\
 		  libgrub_a-zfs_sha256.o	\
+		  libgrub_a-zfs_edonr.o		\
 		  libgrub_a-zfs_lzjb.o		\
 		  libgrub_a-zfs_lz4.o		\
 		  libgrub_a-zfs_fletcher.o	\
@@ -163,6 +164,7 @@
 			  diskless_exec-fsys_minix.o	\
 			  diskless_exec-fsys_reiserfs.o	\
 			  diskless_exec-zfs_sha256.o	\
+			  diskless_exec-zfs_edonr.o	\
 			  diskless_exec-zfs_lzjb.o	\
 			  diskless_exec-zfs_lz4.o	\
 			  diskless_exec-zfs_fletcher.o	\
@@ -375,6 +377,7 @@
 			  pre_stage2_exec-fsys_minix.o \
 			  pre_stage2_exec-fsys_reiserfs.o \
 			  pre_stage2_exec-zfs_sha256.o \
+			  pre_stage2_exec-zfs_edonr.o \
 			  pre_stage2_exec-zfs_lzjb.o \
 			  pre_stage2_exec-zfs_lz4.o \
 			  pre_stage2_exec-zfs_fletcher.o \
@@ -534,6 +537,7 @@
 			  zfs_stage1_5_exec-common.o \
 			  zfs_stage1_5_exec-disk_io.o \
 			  zfs_stage1_5_exec-zfs_sha256.o \
+			  zfs_stage1_5_exec-zfs_edonr.o \
 			  zfs_stage1_5_exec-zfs_lzjb.o \
 			  zfs_stage1_5_exec-zfs_lz4.o \
 			  zfs_stage1_5_exec-zfs_fletcher.o \
@@ -610,15 +614,16 @@
 		  dir.h disk_inode.h disk_inode_ffs.h disk_io.c fat.h \
 		  filesys.h freebsd.h fs.h fsys_ext2fs.c fsys_fat.c \
 		  fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
-		  zfs_sha256.c zfs_lzjb.c zfs_lz4.c zfs_fletcher.c fsys_zfs.c \
-		  fsys_reiserfs.c fsys_ufs.c fsys_ufs2.c fsys_vstafs.c \
-		  fsys_xfs.c graphics.c graphics.h gunzip.c hercules.c \
-		  hercules.h i386-elf.h imgact_aout.h iso9660.h jfs.h \
-		  mb_header.h mb_info.h md5.c md5.h nbi.h nbloader.S \
-		  pc_slice.h pxeloader.S serial.c serial.h setjmp.S shared.h \
-		  size_test smp-imps.c smp-imps.h stage1_5.c stage2.c \
-		  start.S start_eltorito.S term.h terminfo.c terminfo.h \
-		  tparm.c tparm.h fsys_zfs.h ufs.h ufs2.h vstafs.h xfs.h
+		  zfs_sha256.c zfs_edonr.c zfs_lzjb.c zfs_lz4.c \
+		  zfs_fletcher.c fsys_zfs.c fsys_reiserfs.c fsys_ufs.c \
+		  fsys_ufs2.c fsys_vstafs.c fsys_xfs.c graphics.c graphics.h \
+		  gunzip.c hercules.c hercules.h i386-elf.h imgact_aout.h \
+		  iso9660.h jfs.h mb_header.h mb_info.h md5.c md5.h nbi.h \
+		  nbloader.S pc_slice.h pxeloader.S serial.c serial.h \
+		  setjmp.S shared.h size_test smp-imps.c smp-imps.h \
+		  stage1_5.c stage2.c start.S start_eltorito.S term.h \
+		  terminfo.c terminfo.h tparm.c tparm.h fsys_zfs.h ufs.h \
+		  ufs2.h vstafs.h xfs.h
 SRC_ZFSINC_FILES = dmu.h dmu_objset.h dnode.h dsl_dataset.h dsl_dir.h spa.h \
 		uberblock_impl.h vdev_impl.h zap_impl.h zap_leaf.h zfs.h \
 		zfs_acl.h zfs_znode.h zil.h zio.h zio_checksum.h
--- old/usr/src/grub/grub-0.97/stage2/fsys_zfs.c	Tue Feb 19 01:00:51 2013
+++ new/usr/src/grub/grub-0.97/stage2/fsys_zfs.c	Tue Feb 19 01:00:51 2013
@@ -145,6 +145,8 @@
 	{{fletcher_4_native,	fletcher_4_byteswap},	1, 0,	"fletcher4"},
 	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 0,	"SHA256"},
 	{{NULL,			NULL},			0, 0,	"zilog2"},
+	{{zio_checksum_EdonR512_256,	zio_checksum_EdonR512_256_byteswap},
+	    1, 0,	"edonr512/256"}
 };
 
 /*
@@ -963,6 +965,7 @@
  */
 static const char *spa_feature_names[] = {
 	"org.illumos:lz4_compress",
+	"org.illumos:edonr_cksum",
 	NULL
 };
 
--- old/usr/src/grub/grub-0.97/stage2/fsys_zfs.h	Tue Feb 19 01:00:52 2013
+++ new/usr/src/grub/grub-0.97/stage2/fsys_zfs.h	Tue Feb 19 01:00:52 2013
@@ -213,6 +213,9 @@
 extern void fletcher_4_native(const void *, uint64_t, zio_cksum_t *);
 extern void fletcher_4_byteswap(const void *, uint64_t, zio_cksum_t *);
 extern void zio_checksum_SHA256(const void *, uint64_t, zio_cksum_t *);
+extern void zio_checksum_EdonR512_256(const void *, uint64_t, zio_cksum_t *);
+extern void zio_checksum_EdonR512_256_byteswap(const void *, uint64_t,
+    zio_cksum_t *);
 extern int lzjb_decompress(void *, void *, size_t, size_t);
 extern int lz4_decompress(void *, void *, size_t, size_t);
 
--- old/usr/src/grub/grub-0.97/stage2/zfs-include/zio.h	Tue Feb 19 01:00:52 2013
+++ new/usr/src/grub/grub-0.97/stage2/zfs-include/zio.h	Tue Feb 19 01:00:52 2013
@@ -67,6 +67,7 @@
 	ZIO_CHECKSUM_FLETCHER_4,
 	ZIO_CHECKSUM_SHA256,
 	ZIO_CHECKSUM_ZILOG2,
+	ZIO_CHECKSUM_EDONR512_256,
 	ZIO_CHECKSUM_FUNCTIONS
 };
 
--- /dev/null	Tue Feb 19 01:00:52 2013
+++ new/usr/src/grub/grub-0.97/stage2/zfs_edonr.c	Tue Feb 19 01:00:52 2013
@@ -0,0 +1,714 @@
+/*
+ * This code, as well as the Edon-R algorithm itself are public domain.
+ */
+
+#include "fsys_zfs.h"
+#include <string.h>
+
+/* Specific algorithm definitions */
+#define EdonR224_DIGEST_SIZE  28
+#define EdonR224_BLOCK_SIZE   64
+#define EdonR256_DIGEST_SIZE  32
+#define EdonR256_BLOCK_SIZE   64
+#define EdonR384_DIGEST_SIZE  48
+#define EdonR384_BLOCK_SIZE  128
+#define EdonR512_DIGEST_SIZE  64
+#define EdonR512_BLOCK_SIZE  128
+
+static void
+my_memset(void *ptr, int c, size_t n)
+{
+	uint8_t *p;
+	size_t i;
+
+	for (i = 0; i < n; i++)
+		p[i] = c;
+}
+
+typedef struct {
+	uint32_t DoublePipe[32];
+	uint8_t LastPart[EdonR256_BLOCK_SIZE * 2];
+} EdonRData256;
+
+typedef struct {
+	uint64_t DoublePipe[32];
+	uint8_t LastPart[EdonR512_BLOCK_SIZE * 2];
+} EdonRData512;
+
+typedef struct {
+	size_t hashbitlen;
+
+	/* algorithm specific parameters */
+	uint64_t bits_processed;
+	union {
+		EdonRData256 p256[1];
+		EdonRData512 p512[1];
+	} pipe[1];
+	int unprocessed_bits;
+} EdonRHashState;
+
+#define	rotl32(x,n)	(((x) << n) | ((x) >> (32 - n)))
+#define	rotr32(x,n)	(((x) >> n) | ((x) << (32 - n)))
+
+#define	rotl64(x,n)	(((x) << n) | ((x) >> (64 - n)))
+#define	rotr64(x,n)	(((x) >> n) | ((x) << (64 - n)))
+
+/* EdonR224 initial double chaining pipe */
+static const uint32_t i224p2[16] = {
+	0x00010203ul, 0x04050607ul, 0x08090a0bul, 0x0c0d0e0ful,
+	0x10111213ul, 0x14151617ul, 0x18191a1bul, 0x1c1d1e1ful,
+	0x20212223ul, 0x24252627ul, 0x28292a2bul, 0x2c2d2e2ful,
+	0x30313233ul, 0x24353637ul, 0x38393a3bul, 0x3c3d3e3ful
+};
+
+/* EdonR256 initial double chaining pipe */
+static const uint32_t i256p2[16] = {
+	0x40414243ul, 0x44454647ul, 0x48494a4bul, 0x4c4d4e4ful,
+	0x50515253ul, 0x54555657ul, 0x58595a5bul, 0x5c5d5e5ful,
+	0x60616263ul, 0x64656667ul, 0x68696a6bul, 0x6c6d6e6ful,
+	0x70717273ul, 0x74757677ul, 0x78797a7bul, 0x7c7d7e7ful
+};
+
+/* EdonR384 initial double chaining pipe */
+static const uint64_t i384p2[16] = {
+	0x0001020304050607ull, 0x08090a0b0c0d0e0full,
+	0x1011121314151617ull, 0x18191a1b1c1d1e1full,
+	0x2021222324252627ull, 0x28292a2b2c2d2e2full,
+	0x3031323324353637ull, 0x38393a3b3c3d3e3full,
+	0x4041424344454647ull, 0x48494a4b4c4d4e4full,
+	0x5051525354555657ull, 0x58595a5b5c5d5e5full,
+	0x6061626364656667ull, 0x68696a6b6c6d6e6full,
+	0x7071727374757677ull, 0x78797a7b7c7d7e7full
+};
+
+/* EdonR512 initial double chaining pipe */
+const uint64_t i512p2[16] = {
+	0x8081828384858687ull, 0x88898a8b8c8d8e8full,
+	0x9091929394959697ull, 0x98999a9b9c9d9e9full,
+	0xa0a1a2a3a4a5a6a7ull, 0xa8a9aaabacadaeafull,
+	0xb0b1b2b3b4b5b6b7ull, 0xb8b9babbbcbdbebfull,
+	0xc0c1c2c3c4c5c6c7ull, 0xc8c9cacbcccdcecfull,
+	0xd0d1d2d3d4d5d6d7ull, 0xd8d9dadbdcdddedfull,
+	0xe0e1e2e3e4e5e6e7ull, 0xe8e9eaebecedeeefull,
+	0xf0f1f2f3f4f5f6f7ull, 0xf8f9fafbfcfdfeffull
+};
+
+#define	hashState224(x)		((x)->pipe->p256)
+#define	hashState256(x)		((x)->pipe->p256)
+#define	hashState384(x)		((x)->pipe->p512)
+#define	hashState512(x)		((x)->pipe->p512)
+
+#define	Q256(x0, x1, x2, x3, x4, x5, x6, x7, \
+	y0, y1, y2, y3, y4, y5, y6, y7, \
+	z0, z1, z2, z3, z4, z5, z6, z7) \
+{\
+	/* First Latin Square\
+	0   7   1   3   2   4   6   5\
+	4   1   7   6   3   0   5   2\
+	7   0   4   2   5   3   1   6\
+	1   4   0   5   6   2   7   3\
+	2   3   6   7   1   5   0   4\
+	5   2   3   1   7   6   4   0\
+	3   6   5   0   4   7   2   1\
+	6   5   2   4   0   1   3   7\
+	*/\
+	t8  =  x0 + x4;\
+	t9  =  x1 + x7;\
+	t12 =  t8 + t9;\
+	t10 =  x2 + x3;\
+	t11 =  x5 + x6;\
+	t13 = t10 + t11;\
+	t0 = 0xaaaaaaaa + t12 +  x2;\
+	t1 = t12 + x3;\
+	t1 = rotl32((t1), 5);\
+	t2 = t12 + x6;\
+	t2 = rotl32((t2),11);\
+	t3 = t13 + x7;\
+	t3 = rotl32((t3),13);\
+	t4 = x1 + t13;\
+	t4 = rotl32((t4),17);\
+	t5 = t8 + t10 + x5;\
+	t5 = rotl32((t5),19);\
+	t6 = x0 + t9 + t11;\
+	t6 = rotl32((t6),29);\
+	t7 = t13 +x4;\
+	t7 = rotl32((t7),31);\
+	\
+	t16 = t0 ^ t4;\
+	t17 = t1 ^ t7;\
+	t18 = t2 ^ t3;\
+	t19 = t5 ^ t6;\
+	t8  = t3 ^ t19;\
+	t9  = t2 ^ t19;\
+	t10 = t18 ^ t5;\
+	t11 = t16^ t1;\
+	t12 = t16 ^ t7;\
+	t13 = t17 ^ t6;\
+	t14 = t18 ^ t4;\
+	t15 = t0 ^ t17;\
+	\
+	/* Second Orthogonal Latin Square\
+	0   4   2   3   1   6   5   7\
+	7   6   3   2   5   4   1   0\
+	5   3   1   6   0   2   7   4\
+	1   0   5   4   3   7   2   6\
+	2   1   0   7   4   5   6   3\
+	3   5   7   0   6   1   4   2\
+	4   7   6   1   2   0   3   5\
+	6   2   4   5   7   3   0   1\
+	*/\
+	t16 = y0  + y1;\
+	t17 = y2  + y5;\
+	t20 = t16 + t17;\
+	t18 = y3  + y4;\
+	t22 = t16 + t18;\
+	t19 = y6  + y7;\
+	t21 = t18 + t19;\
+	t23 = t17 + t19;\
+	t0  = 0x55555555 + t20 + y7;\
+	t1  = t22 + y6;\
+	t1  = rotl32((t1), 3);\
+	t2  = t20 + y3;\
+	t2  = rotl32((t2), 7);\
+	t3  = y2 + t21;\
+	t3  = rotl32((t3),11);\
+	t4  = t22 + y5;\
+	t4  = rotl32((t4),17);\
+	t5  = t23 + y4;\
+	t5  = rotl32((t5),19);\
+	t6  = y1 + t23;\
+	t6  = rotl32((t6),23);\
+	t7  = y0 + t21;\
+	t7  = rotl32((t7),29);\
+	\
+	t16 = t0 ^ t1;\
+	t17 = t2 ^ t5;\
+	t18 = t3 ^ t4;\
+	t19 = t6 ^ t7;\
+	z5  = t8  + (t18 ^ t6);\
+	z6  = t9  + (t17 ^ t7);\
+	z7  = t10 + (t4 ^ t19);\
+	z0  = t11 + (t16 ^ t5);\
+	z1  = t12 + (t2 ^ t19);\
+	z2  = t13 + (t16 ^ t3);\
+	z3  = t14 + (t0 ^ t18);\
+	z4  = t15 + (t1 ^ t17);\
+}
+
+#define	Q512(x0, x1, x2, x3, x4, x5, x6, x7, \
+	y0, y1, y2, y3, y4, y5, y6, y7,\
+	z0, z1, z2, z3, z4, z5, z6, z7) \
+{\
+	/* First Latin Square\
+	0   7   1   3   2   4   6   5\
+	4   1   7   6   3   0   5   2\
+	7   0   4   2   5   3   1   6\
+	1   4   0   5   6   2   7   3\
+	2   3   6   7   1   5   0   4\
+	5   2   3   1   7   6   4   0\
+	3   6   5   0   4   7   2   1\
+	6   5   2   4   0   1   3   7\
+	*/\
+	tt8  = x0 + x4;\
+	tt9  = x1 + x7;\
+	tt12 = tt8 + tt9;\
+	tt10 = x2 + x3;\
+	tt11 = x5 + x6;\
+	tt13 = tt10 + tt11;\
+	tt0  = 0xaaaaaaaaaaaaaaaaull + tt12 + x2;\
+	tt1  = tt12 + x3;\
+	tt1  = rotl64((tt1), 5);\
+	tt2  = tt12 + x6;\
+	tt2  = rotl64((tt2),19);\
+	tt3  = tt13 + x7;\
+	tt3  = rotl64((tt3),29);\
+	tt4  = x1 + tt13;\
+	tt4  = rotl64((tt4),31);\
+	tt5  = tt8 + tt10 + x5;\
+	tt5  = rotl64((tt5),41);\
+	tt6  = x0 + tt9 + tt11;\
+	tt6  = rotl64((tt6),57);\
+	tt7  = tt13 + x4;\
+	tt7  = rotl64((tt7),61);\
+	\
+	tt16 = tt0 ^ tt4;\
+	tt17 = tt1 ^ tt7;\
+	tt18 = tt2 ^ tt3;\
+	tt19 = tt5 ^ tt6;\
+	tt8  = tt3 ^ tt19;\
+	tt9  = tt2 ^ tt19;\
+	tt10 = tt18 ^ tt5;\
+	tt11 = tt16 ^ tt1;\
+	tt12 = tt16 ^ tt7;\
+	tt13 = tt17 ^ tt6;\
+	tt14 = tt18 ^ tt4;\
+	tt15 = tt0 ^ tt17;\
+	\
+	/* Second Orthogonal Latin Square\
+	0   4   2   3   1   6   5   7\
+	7   6   3   2   5   4   1   0\
+	5   3   1   6   0   2   7   4\
+	1   0   5   4   3   7   2   6\
+	2   1   0   7   4   5   6   3\
+	3   5   7   0   6   1   4   2\
+	4   7   6   1   2   0   3   5\
+	6   2   4   5   7   3   0   1\
+	*/\
+	tt16 = y0  + y1;\
+	tt17 = y2  + y5;\
+	tt20 = tt16 + tt17;\
+	tt18 = y3  + y4;\
+	tt22 = tt16 + tt18;\
+	tt19 = y6  + y7;\
+	tt21 = tt18 + tt19;\
+	tt23 = tt17 + tt19;\
+	tt0  = 0x5555555555555555ull + tt20 + y7;\
+	tt1  = tt22 + y6;\
+	tt1  = rotl64((tt1), 3);\
+	tt2  = tt20 + y3;\
+	tt2  = rotl64((tt2),17);\
+	tt3  = y2 + tt21;\
+	tt3  = rotl64((tt3),23);\
+	tt4  = tt22 + y5;\
+	tt4  = rotl64((tt4),31);\
+	tt5  = tt23+ y4;\
+	tt5  = rotl64((tt5),37);\
+	tt6  = y1 + tt23;\
+	tt6  = rotl64((tt6),45);\
+	tt7  = y0 + tt21;\
+	tt7  = rotl64((tt7),59);\
+	\
+	tt16 = tt0 ^ tt1;\
+	tt17 = tt2 ^ tt5;\
+	tt18 = tt3 ^ tt4;\
+	tt19 = tt6 ^ tt7;\
+	z5   = tt8  + (tt18 ^ tt6);\
+	z6   = tt9  + (tt17 ^ tt7);\
+	z7   = tt10 + (tt4  ^ tt19);\
+	z0   = tt11 + (tt16 ^ tt5);\
+	z1   = tt12 + (tt2  ^ tt19);\
+	z2   = tt13 + (tt16 ^ tt3);\
+	z3   = tt14 + (tt0  ^ tt18);\
+	z4   = tt15 + (tt1  ^ tt17);\
+}
+
+static void
+EdonRInit(EdonRHashState *state, int hashbitlen)
+{
+	switch (hashbitlen) {
+	case 224:
+		state->hashbitlen = 224;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		memcpy(hashState224(state)->DoublePipe, i224p2,
+		    16 * sizeof (uint32_t));
+		break;
+
+	case 256:
+		state->hashbitlen = 256;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		memcpy(hashState256(state)->DoublePipe, i256p2,
+		    16 * sizeof (uint32_t));
+		break;
+
+	case 384:
+		state->hashbitlen = 384;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		memcpy(hashState384(state)->DoublePipe, i384p2,
+		    16 * sizeof (uint64_t));
+		break;
+
+	case 512:
+		state->hashbitlen = 512;
+		state->bits_processed = 0;
+		state->unprocessed_bits = 0;
+		memcpy(hashState224(state)->DoublePipe, i512p2,
+		    16 * sizeof (uint64_t));
+		break;
+	}
+}
+
+static void
+EdonRUpdate(EdonRHashState *state, const uint8_t *data, size_t databitlen)
+{
+	uint32_t *data32, *p256;
+	uint32_t t0, t1, t2, t3, t4, t5, t6, t7;
+	uint32_t t8, t9, t10, t11, t12, t13, t14, t15;
+	uint32_t t16, t17, t18, t19, t20, t21, t22, t23;
+	uint32_t p16, p17, p18, p19, p20, p21, p22, p23;
+	uint32_t p24, p25, p26, p27, p28, p29, p30, p31;
+
+	uint64_t *data64, *p512;
+	uint64_t tt0, tt1, tt2, tt3, tt4, tt5, tt6, tt7;
+	uint64_t tt8, tt9, tt10, tt11, tt12, tt13, tt14, tt15;
+	uint64_t tt16, tt17, tt18, tt19, tt20, tt21, tt22, tt23;
+	uint64_t pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23;
+	uint64_t pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31;
+
+	int LastBytes;
+
+	switch (state->hashbitlen) {
+	case 224:
+	case 256:
+		if (state->unprocessed_bits > 0) {
+			/* LastBytes = databitlen / 8 */
+			LastBytes = (int) databitlen >> 3;
+			memcpy(hashState256(state)->LastPart +
+			    (state->unprocessed_bits >> 3), data, LastBytes);
+			state->unprocessed_bits += (int) databitlen;
+			databitlen = state->unprocessed_bits;
+			data32 = (uint32_t *) hashState256(state)->LastPart;
+		} else
+			data32 = (uint32_t *) data;
+
+		p256 = hashState256(state)->DoublePipe;
+		while (databitlen >= EdonR256_BLOCK_SIZE * 8) {
+			databitlen -= EdonR256_BLOCK_SIZE * 8;
+
+			state->bits_processed += EdonR256_BLOCK_SIZE * 8;
+
+			/* First row of quasigroup e-transformations */
+			Q256(data32[15], data32[14], data32[13], data32[12],
+			    data32[11], data32[10], data32[9], data32[8],
+			    data32[0], data32[1], data32[2], data32[3],
+			    data32[4], data32[5], data32[6], data32[7], p16,
+			    p17, p18, p19, p20, p21, p22, p23);
+			Q256(p16, p17, p18, p19, p20, p21, p22, p23, data32[8],
+			    data32[9], data32[10], data32[11], data32[12],
+			    data32[13], data32[14], data32[15], p24, p25, p26,
+			    p27, p28, p29, p30, p31);
+
+			/* Second row of quasigroup e-transformations */
+			Q256(p256[8], p256[9], p256[10], p256[11], p256[12],
+			    p256[13], p256[14], p256[15], p16, p17, p18, p19,
+			    p20, p21, p22, p23, p16, p17, p18, p19, p20, p21,
+			    p22, p23);
+			Q256(p16, p17, p18, p19, p20, p21, p22, p23, p24, p25,
+			    p26, p27, p28, p29, p30, p31, p24, p25, p26, p27,
+			    p28, p29, p30, p31);
+
+			/* Third row of quasigroup e-transformations */
+			Q256(p16, p17, p18, p19, p20, p21, p22, p23,
+			    p256[0], p256[1], p256[2], p256[3], p256[4],
+			    p256[5], p256[6], p256[7], p16, p17, p18, p19, p20,
+			    p21, p22, p23);
+			Q256(p24, p25, p26, p27, p28, p29, p30, p31, p16, p17,
+			    p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
+			    p28, p29, p30, p31);
+
+			/* Fourth row of quasigroup e-transformations */
+			Q256(data32[7], data32[6], data32[5], data32[4],
+			    data32[3], data32[2], data32[1], data32[0], p16,
+			    p17, p18, p19, p20, p21, p22, p23, p256[0], p256[1],
+			    p256[2], p256[3], p256[4], p256[5], p256[6],
+			    p256[7]);
+			Q256(p256[0], p256[1], p256[2], p256[3], p256[4],
+			    p256[5], p256[6], p256[7], p24, p25, p26, p27, p28,
+			    p29, p30, p31, p256[8], p256[9], p256[10], p256[11],
+			    p256[12], p256[13], p256[14], p256[15]);
+
+			data32 += 16;
+		}
+		state->unprocessed_bits = (int) databitlen;
+		if (databitlen > 0) {
+			/* LastBytes = Ceil(databitlen / 8) */
+			LastBytes = ((~(((-(int) databitlen) >> 3) & 0x01ff)) +
+			    1) & 0x01ff;
+			memcpy(hashState256(state)->LastPart, data32,
+			    LastBytes);
+		}
+		break;
+
+
+	case 384:
+	case 512:
+		if (state->unprocessed_bits > 0) {
+			/* LastBytes = databitlen / 8 */
+			LastBytes = (int) databitlen >> 3;
+			memcpy(hashState512(state)->LastPart +
+			    (state->unprocessed_bits >> 3), data, LastBytes);
+			state->unprocessed_bits += (int) databitlen;
+			databitlen = state->unprocessed_bits;
+			data64 = (uint64_t *) hashState512(state)->LastPart;
+		} else
+			data64 = (uint64_t *) data;
+
+		p512 = hashState512(state)->DoublePipe;
+		while (databitlen >= EdonR512_BLOCK_SIZE * 8) {
+			databitlen -= EdonR512_BLOCK_SIZE * 8;
+
+			state->bits_processed += EdonR512_BLOCK_SIZE * 8;
+
+			/* First row of quasigroup e-transformations */
+			Q512(data64[15], data64[14], data64[13], data64[12],
+			    data64[11], data64[10], data64[9], data64[8],
+			    data64[0], data64[1], data64[2], data64[3],
+			    data64[4], data64[5], data64[6], data64[7], pp16,
+			    pp17, pp18, pp19, pp20, pp21, pp22, pp23);
+			Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    data64[8], data64[9], data64[10], data64[11],
+			    data64[12], data64[13], data64[14], data64[15],
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
+
+			/* Second row of quasigroup e-transformations */
+			Q512(p512[8], p512[9], p512[10], p512[11], p512[12],
+			    p512[13], p512[14], p512[15], pp16, pp17, pp18,
+			    pp19, pp20, pp21, pp22, pp23, pp16, pp17, pp18,
+			    pp19, pp20, pp21, pp22, pp23);
+			Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
+
+			/* Third row of quasigroup e-transformations */
+			Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    p512[0], p512[1], p512[2], p512[3], p512[4],
+			    p512[5], p512[6], p512[7], pp16, pp17, pp18, pp19,
+			    pp20, pp21, pp22, pp23);
+			Q512(pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
+			    pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
+
+			/* Fourth row of quasigroup e-transformations */
+			Q512(data64[7], data64[6], data64[5], data64[4],
+			    data64[3], data64[2], data64[1], data64[0], pp16,
+			    pp17, pp18, pp19, pp20, pp21, pp22, pp23, p512[0],
+			    p512[1], p512[2], p512[3], p512[4], p512[5],
+			    p512[6], p512[7]);
+			Q512(p512[0], p512[1], p512[2], p512[3], p512[4],
+			    p512[5], p512[6], p512[7], pp24, pp25, pp26, pp27,
+			    pp28, pp29, pp30, pp31, p512[8], p512[9], p512[10],
+			    p512[11], p512[12], p512[13], p512[14], p512[15]);
+
+			data64 += 16;
+		}
+		state->unprocessed_bits = (int) databitlen;
+		if (databitlen > 0) {
+			/* LastBytes = Ceil(databitlen / 8) */
+			LastBytes = ((~(((-(int) databitlen) >> 3) & 0x03ff)) +
+			    1) & 0x03ff;
+			memcpy(hashState512(state)->LastPart, data64,
+			    LastBytes);
+		}
+		break;
+	}
+}
+
+static void
+EdonRFinal(EdonRHashState * state, uint8_t *hashval)
+{
+	uint32_t *data32, *p256;
+	uint32_t t0, t1, t2, t3, t4, t5, t6, t7;
+	uint32_t t8, t9, t10, t11, t12, t13, t14, t15;
+	uint32_t t16, t17, t18, t19, t20, t21, t22, t23;
+	uint32_t p16, p17, p18, p19, p20, p21, p22, p23;
+	uint32_t p24, p25, p26, p27, p28, p29, p30, p31;
+
+	uint64_t *data64, *p512;
+	uint64_t tt0, tt1, tt2, tt3, tt4, tt5, tt6, tt7;
+	uint64_t tt8, tt9, tt10, tt11, tt12, tt13, tt14, tt15;
+	uint64_t tt16, tt17, tt18, tt19, tt20, tt21, tt22, tt23;
+	uint64_t pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23;
+	uint64_t pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31;
+
+	size_t databitlen;
+
+	int LastByte, PadOnePosition;
+
+	switch (state->hashbitlen) {
+	case 224:
+	case 256:
+		LastByte = (int) state->unprocessed_bits >> 3;
+		PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
+		hashState256(state)->LastPart[LastByte] =
+		    hashState256(state)->
+		    LastPart[LastByte] & (0xff << (PadOnePosition + 1))
+		    ^ (0x01 << PadOnePosition);
+		data64 = (uint64_t *) hashState256(state)->LastPart;
+
+		if (state->unprocessed_bits < 448) {
+			my_memset((hashState256(state)->LastPart) + LastByte +
+			    1, 0x00, EdonR256_BLOCK_SIZE - LastByte - 9);
+			databitlen = EdonR256_BLOCK_SIZE * 8;
+			data64[7] =
+			    state->bits_processed + state->unprocessed_bits;
+		} else {
+			my_memset((hashState256(state)->LastPart) + LastByte +
+			    1, 0x00, EdonR256_BLOCK_SIZE * 2 - LastByte - 9);
+			databitlen = EdonR256_BLOCK_SIZE * 16;
+			data64[15] =
+			    state->bits_processed + state->unprocessed_bits;
+		}
+
+		data32 = (uint32_t *) hashState256(state)->LastPart;
+		p256 = hashState256(state)->DoublePipe;
+		while (databitlen >= EdonR256_BLOCK_SIZE * 8) {
+			databitlen -= EdonR256_BLOCK_SIZE * 8;
+
+			/* First row of quasigroup e-transformations */
+			Q256(data32[15], data32[14], data32[13], data32[12],
+			    data32[11], data32[10], data32[9], data32[8],
+			    data32[0], data32[1], data32[2], data32[3],
+			    data32[4], data32[5], data32[6], data32[7], p16,
+			    p17, p18, p19, p20, p21, p22, p23);
+			Q256(p16, p17, p18, p19, p20, p21, p22, p23, data32[8],
+			    data32[9], data32[10], data32[11], data32[12],
+			    data32[13], data32[14], data32[15], p24, p25, p26,
+			    p27, p28, p29, p30, p31);
+
+			/* Second row of quasigroup e-transformations */
+			Q256(p256[8], p256[9], p256[10], p256[11], p256[12],
+			    p256[13], p256[14], p256[15], p16, p17, p18, p19,
+			    p20, p21, p22, p23, p16, p17, p18, p19, p20, p21,
+			    p22, p23);
+			Q256(p16, p17, p18, p19, p20, p21, p22, p23, p24, p25,
+			    p26, p27, p28, p29, p30, p31, p24, p25, p26, p27,
+			    p28, p29, p30, p31);
+
+			/* Third row of quasigroup e-transformations */
+			Q256(p16, p17, p18, p19, p20, p21, p22, p23,
+			    p256[0], p256[1], p256[2], p256[3], p256[4],
+			    p256[5], p256[6], p256[7], p16, p17, p18, p19, p20,
+			    p21, p22, p23);
+			Q256(p24, p25, p26, p27, p28, p29, p30, p31, p16, p17,
+			    p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
+			    p28, p29, p30, p31);
+
+			/* Fourth row of quasigroup e-transformations */
+			Q256(data32[7], data32[6], data32[5], data32[4],
+			    data32[3], data32[2], data32[1], data32[0], p16,
+			    p17, p18, p19, p20, p21, p22, p23, p256[0], p256[1],
+			    p256[2], p256[3], p256[4], p256[5], p256[6],
+			    p256[7]);
+			Q256(p256[0], p256[1], p256[2], p256[3], p256[4],
+			    p256[5], p256[6], p256[7], p24, p25, p26, p27, p28,
+			    p29, p30, p31, p256[8], p256[9], p256[10], p256[11],
+			    p256[12], p256[13], p256[14], p256[15]);
+
+
+			data32 += 16;
+		}
+		break;
+
+	case 384:
+	case 512:
+		LastByte = (int) state->unprocessed_bits >> 3;
+		PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
+		hashState512(state)->LastPart[LastByte] =
+		    hashState512(state)->
+		    LastPart[LastByte] & (0xff << (PadOnePosition + 1))
+		    ^ (0x01 << PadOnePosition);
+		data64 = (uint64_t *) hashState512(state)->LastPart;
+
+		if (state->unprocessed_bits < 960) {
+			my_memset((hashState512(state)->LastPart) + LastByte +
+			    1, 0x00, EdonR512_BLOCK_SIZE - LastByte - 9);
+			databitlen = EdonR512_BLOCK_SIZE * 8;
+			data64[15] =
+			    state->bits_processed + state->unprocessed_bits;
+		} else {
+			my_memset((hashState512(state)->LastPart) + LastByte +
+			    1, 0x00, EdonR512_BLOCK_SIZE * 2 - LastByte - 9);
+			databitlen = EdonR512_BLOCK_SIZE * 16;
+			data64[31] =
+			    state->bits_processed + state->unprocessed_bits;
+		}
+
+		p512 = hashState512(state)->DoublePipe;
+		while (databitlen >= EdonR512_BLOCK_SIZE * 8) {
+			databitlen -= EdonR512_BLOCK_SIZE * 8;
+			/* First row of quasigroup e-transformations */
+			Q512(data64[15], data64[14], data64[13], data64[12],
+			    data64[11], data64[10], data64[9], data64[8],
+			    data64[0], data64[1], data64[2], data64[3],
+			    data64[4], data64[5], data64[6], data64[7], pp16,
+			    pp17, pp18, pp19, pp20, pp21, pp22, pp23);
+			Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    data64[8], data64[9], data64[10], data64[11],
+			    data64[12], data64[13], data64[14], data64[15],
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
+
+			/* Second row of quasigroup e-transformations */
+			Q512(p512[8], p512[9], p512[10], p512[11], p512[12],
+			    p512[13], p512[14], p512[15], pp16, pp17, pp18,
+			    pp19, pp20, pp21, pp22, pp23, pp16, pp17, pp18,
+			    pp19, pp20, pp21, pp22, pp23);
+			Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
+
+			/* Third row of quasigroup e-transformations */
+			Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    p512[0], p512[1], p512[2], p512[3], p512[4],
+			    p512[5], p512[6], p512[7], pp16, pp17, pp18, pp19,
+			    pp20, pp21, pp22, pp23);
+			Q512(pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
+			    pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
+			    pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
+
+			/* Fourth row of quasigroup e-transformations */
+			Q512(data64[7], data64[6], data64[5], data64[4],
+			    data64[3], data64[2], data64[1], data64[0], pp16,
+			    pp17, pp18, pp19, pp20, pp21, pp22, pp23, p512[0],
+			    p512[1], p512[2], p512[3], p512[4], p512[5],
+			    p512[6], p512[7]);
+			Q512(p512[0], p512[1], p512[2], p512[3], p512[4],
+			    p512[5], p512[6], p512[7], pp24, pp25, pp26, pp27,
+			    pp28, pp29, pp30, pp31, p512[8], p512[9], p512[10],
+			    p512[11], p512[12], p512[13], p512[14], p512[15]);
+
+			data64 += 16;
+		}
+		break;
+	}
+
+	switch (state->hashbitlen) {
+	case 224:
+		memcpy(hashval, p256 + 9, EdonR224_DIGEST_SIZE);
+		break;
+	case 256:
+		memcpy(hashval, p256 + 8, EdonR256_DIGEST_SIZE);
+		break;
+	case 384:
+		memcpy(hashval, p512 + 10, EdonR384_DIGEST_SIZE);
+		break;
+	case 512:
+		memcpy(hashval, p512 + 8, EdonR512_DIGEST_SIZE);
+		break;
+	}
+}
+
+static void
+EdonRHash(size_t hashbitlen, const uint8_t* data, size_t databitlen,
+    uint8_t *hashval)
+{
+	EdonRHashState state;
+
+	EdonRInit(&state, hashbitlen);
+	EdonRUpdate(&state, data, databitlen);
+	EdonRFinal(&state, hashval);
+}
+
+void
+zio_checksum_EdonR512_256(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	uint8_t hash[EdonR512_DIGEST_SIZE];
+
+	EdonRHash(512, buf, size * 8, hash);
+	memcpy(&zcp->zc_word[0], &hash[000], sizeof (zcp->zc_word[0]));
+	memcpy(&zcp->zc_word[1], &hash[010], sizeof (zcp->zc_word[1]));
+	memcpy(&zcp->zc_word[2], &hash[020], sizeof (zcp->zc_word[2]));
+	memcpy(&zcp->zc_word[3], &hash[030], sizeof (zcp->zc_word[3]));
+}
+
+void
+zio_checksum_EdonR512_256_byteswap(const void *buf, uint64_t size,
+    zio_cksum_t *zcp)
+{
+	zio_checksum_EdonR512_256(buf, size, zcp);
+	zcp->zc_word[0] = BSWAP_64(zcp->zc_word[0]);
+	zcp->zc_word[1] = BSWAP_64(zcp->zc_word[1]);
+	zcp->zc_word[2] = BSWAP_64(zcp->zc_word[2]);
+	zcp->zc_word[3] = BSWAP_64(zcp->zc_word[3]);
+}
--- old/usr/src/pkg/manifests/system-header.mf	Tue Feb 19 01:00:52 2013
+++ new/usr/src/pkg/manifests/system-header.mf	Tue Feb 19 01:00:52 2013
@@ -945,6 +945,7 @@
 file path=usr/include/sys/ecppreg.h
 file path=usr/include/sys/ecppsys.h
 file path=usr/include/sys/ecppvar.h
+file path=usr/include/sys/edonr.h
 file path=usr/include/sys/efi_partition.h
 file path=usr/include/sys/elf.h
 file path=usr/include/sys/elf_386.h
--- old/usr/src/pkg/manifests/system-kernel.mf	Tue Feb 19 01:00:52 2013
+++ new/usr/src/pkg/manifests/system-kernel.mf	Tue Feb 19 01:00:52 2013
@@ -303,6 +303,7 @@
 file path=kernel/crypto/$(ARCH64)/blowfish group=sys mode=0755
 file path=kernel/crypto/$(ARCH64)/des group=sys mode=0755
 file path=kernel/crypto/$(ARCH64)/ecc group=sys mode=0755
+file path=kernel/crypto/$(ARCH64)/edonr group=sys mode=0755
 file path=kernel/crypto/$(ARCH64)/md4 group=sys mode=0755
 file path=kernel/crypto/$(ARCH64)/md5 group=sys mode=0755
 file path=kernel/crypto/$(ARCH64)/rsa group=sys mode=0755
@@ -314,6 +315,7 @@
 $(i386_ONLY)file path=kernel/crypto/blowfish group=sys mode=0755
 $(i386_ONLY)file path=kernel/crypto/des group=sys mode=0755
 $(i386_ONLY)file path=kernel/crypto/ecc group=sys mode=0755
+$(i386_ONLY)file path=kernel/crypto/edonr group=sys mode=0755
 $(i386_ONLY)file path=kernel/crypto/md4 group=sys mode=0755
 $(i386_ONLY)file path=kernel/crypto/md5 group=sys mode=0755
 $(i386_ONLY)file path=kernel/crypto/rsa group=sys mode=0755
@@ -817,6 +819,8 @@
 $(i386_ONLY)file path=usr/share/man/man7d/smbios.7d
 # Sadly vuid mouse support is in different packages on different platforms
 # While kstat(7D) is in SUNWcs, the structures are general
+hardlink path=kernel/misc/$(ARCH64)/edonr \
+    target=../../../kernel/crypto/$(ARCH64)/edonr
 hardlink path=kernel/misc/$(ARCH64)/md5 \
     target=../../../kernel/crypto/$(ARCH64)/md5
 hardlink path=kernel/misc/$(ARCH64)/sha1 \
@@ -823,6 +827,7 @@
     target=../../../kernel/crypto/$(ARCH64)/sha1
 hardlink path=kernel/misc/$(ARCH64)/sha2 \
     target=../../../kernel/crypto/$(ARCH64)/sha2
+$(i386_ONLY)hardlink path=kernel/misc/edonr target=../../kernel/crypto/edonr
 $(i386_ONLY)hardlink path=kernel/misc/md5 target=../../kernel/crypto/md5
 $(i386_ONLY)hardlink path=kernel/misc/sha1 target=../../kernel/crypto/sha1
 $(i386_ONLY)hardlink path=kernel/misc/sha2 target=../../kernel/crypto/sha2
--- old/usr/src/uts/common/Makefile.files	Tue Feb 19 01:00:53 2013
+++ new/usr/src/uts/common/Makefile.files	Tue Feb 19 01:00:53 2013
@@ -499,6 +499,8 @@
 
 SAD_OBJS +=	sad.o
 
+EDONR_OBJS +=	edonr.o
+
 MD4_OBJS +=	md4.o md4_mod.o
 
 MD5_OBJS +=	md5.o md5_mod.o
@@ -1383,6 +1385,7 @@
 	zap_micro.o		\
 	zfs_byteswap.o		\
 	zfs_debug.o		\
+	zfs_edonr.o		\
 	zfs_fm.o		\
 	zfs_fuid.o		\
 	zfs_sa.o		\
--- old/usr/src/uts/common/Makefile.rules	Tue Feb 19 01:00:53 2013
+++ new/usr/src/uts/common/Makefile.rules	Tue Feb 19 01:00:53 2013
@@ -1488,6 +1488,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:		$(COMMONBASE)/crypto/edonr/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:		$(COMMONBASE)/crypto/sha1/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -2614,6 +2618,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/rpc/sec_gss/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(COMMONBASE)/crypto/edonr/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(COMMONBASE)/crypto/sha1/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- old/usr/src/uts/common/fs/zfs/sys/zio.h	Tue Feb 19 01:00:53 2013
+++ new/usr/src/uts/common/fs/zfs/sys/zio.h	Tue Feb 19 01:00:53 2013
@@ -79,6 +79,7 @@
 	ZIO_CHECKSUM_FLETCHER_4,
 	ZIO_CHECKSUM_SHA256,
 	ZIO_CHECKSUM_ZILOG2,
+	ZIO_CHECKSUM_EDONR512_256,
 	ZIO_CHECKSUM_FUNCTIONS
 };
 
--- old/usr/src/uts/common/fs/zfs/sys/zio_checksum.h	Tue Feb 19 01:00:53 2013
+++ new/usr/src/uts/common/fs/zfs/sys/zio_checksum.h	Tue Feb 19 01:00:53 2013
@@ -62,6 +62,8 @@
  * Checksum routines.
  */
 extern zio_checksum_t zio_checksum_SHA256;
+extern zio_checksum_t zio_checksum_EdonR512_256;
+extern zio_checksum_t zio_checksum_EdonR512_256_byteswap;
 
 extern void zio_checksum_compute(zio_t *zio, enum zio_checksum checksum,
     void *data, uint64_t size);
--- /dev/null	Tue Feb 19 01:00:53 2013
+++ new/usr/src/uts/common/fs/zfs/zfs_edonr.c	Tue Feb 19 01:00:53 2013
@@ -0,0 +1,53 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2013 Saso Kiselkov.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <sys/zfs_context.h>
+#include <sys/zio.h>
+#include <sys/edonr.h>
+
+/*
+ * zio_checksum interface for the Edon-R hash function
+ */
+void
+zio_checksum_EdonR512_256(const void *buf, uint64_t size, zio_cksum_t *zcp)
+{
+	uint8_t hash[EdonR512_DIGEST_SIZE];
+
+	EdonRHash(512, buf, size * 8, hash);
+	bcopy(&hash[000], &zcp->zc_word[0], sizeof (zcp->zc_word[0]));
+	bcopy(&hash[010], &zcp->zc_word[1], sizeof (zcp->zc_word[0]));
+	bcopy(&hash[020], &zcp->zc_word[2], sizeof (zcp->zc_word[0]));
+	bcopy(&hash[030], &zcp->zc_word[3], sizeof (zcp->zc_word[0]));
+}
+
+void
+zio_checksum_EdonR512_256_byteswap(const void *buf, uint64_t size,
+    zio_cksum_t *zcp)
+{
+	zio_checksum_EdonR512_256(buf, size, zcp);
+	zcp->zc_word[0] = BSWAP_64(zcp->zc_word[0]);
+	zcp->zc_word[1] = BSWAP_64(zcp->zc_word[1]);
+	zcp->zc_word[2] = BSWAP_64(zcp->zc_word[2]);
+	zcp->zc_word[3] = BSWAP_64(zcp->zc_word[3]);
+}
--- old/usr/src/uts/common/fs/zfs/zfs_ioctl.c	Tue Feb 19 01:00:53 2013
+++ new/usr/src/uts/common/fs/zfs/zfs_ioctl.c	Tue Feb 19 01:00:53 2013
@@ -2391,6 +2391,40 @@
 		}
 		break;
 	}
+	case ZFS_PROP_CHECKSUM:
+	{
+		if (intval == ZIO_CHECKSUM_EDONR512_256) {
+			zfeature_info_t *feature =
+			    &spa_feature_table[SPA_FEATURE_EDONR_CKSUM];
+			spa_t *spa;
+			dsl_pool_t *dp;
+
+			if ((err = spa_open(dsname, &spa, FTAG)) != 0)
+				return (err);
+
+			dp = spa->spa_dsl_pool;
+
+			/*
+			 * Setting the Edon-R checksum algorithm activates
+			 * the feature.
+			 */
+			if (!spa_feature_is_active(spa, feature)) {
+				if ((err = zfs_prop_activate_feature(dp,
+				    feature)) != 0) {
+					spa_close(spa, FTAG);
+					return (err);
+				}
+			}
+
+			spa_close(spa, FTAG);
+		}
+		/*
+		 * We still want the default set action to be performed in the
+		 * caller, we only performed zfeature settings here.
+		 */
+		err = -1;
+		break;
+	}
 	case ZFS_PROP_COMPRESSION:
 	{
 		if (intval == ZIO_COMPRESS_LZ4) {
@@ -3649,6 +3683,25 @@
 	 * Check that this value is valid for this pool version
 	 */
 	switch (prop) {
+	case ZFS_PROP_CHECKSUM:
+		if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
+		    nvpair_value_uint64(pair, &intval) == 0) {
+			if (intval == ZIO_CHECKSUM_EDONR512_256) {
+				zfeature_info_t *feature =
+				    &spa_feature_table[SPA_FEATURE_EDONR_CKSUM];
+				spa_t *spa;
+
+				if ((err = spa_open(dsname, &spa, FTAG)) != 0)
+					return (err);
+
+				if (!spa_feature_is_enabled(spa, feature)) {
+					spa_close(spa, FTAG);
+					return (ENOTSUP);
+				}
+				spa_close(spa, FTAG);
+			}
+		}
+		break;
 	case ZFS_PROP_COMPRESSION:
 		/*
 		 * If the user specified gzip compression, make sure
--- old/usr/src/uts/common/fs/zfs/zio_checksum.c	Tue Feb 19 01:00:54 2013
+++ new/usr/src/uts/common/fs/zfs/zio_checksum.c	Tue Feb 19 01:00:54 2013
@@ -77,6 +77,8 @@
 	{{fletcher_4_native,	fletcher_4_byteswap},	1, 0, 0, "fletcher4"},
 	{{zio_checksum_SHA256,	zio_checksum_SHA256},	1, 0, 1, "sha256"},
 	{{fletcher_4_native,	fletcher_4_byteswap},	0, 1, 0, "zilog2"},
+	{{zio_checksum_EdonR512_256,	zio_checksum_EdonR512_256_byteswap},
+	    1, 0, 1, "edonr512/256"},
 };
 
 enum zio_checksum
--- /dev/null	Tue Feb 19 01:00:54 2013
+++ new/usr/src/uts/common/sys/edonr.h	Tue Feb 19 01:00:54 2013
@@ -0,0 +1,85 @@
+/*
+ * IDI,NTNU
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright (C) 2009, 2010, Jorn Amundsen <jorn.amundsen@ntnu.no>
+ *
+ * Tweaked Edon-R implementation for SUPERCOP, based on NIST API.
+ *
+ * $Id: edonr.h 517 2013-02-17 20:34:39Z joern $
+ */
+/*
+ * Portions copyright (c) 2013, Saso Kiselkov, All rights reserved
+ */
+
+#ifndef	__EDONR_H__
+#define	__EDONR_H__
+
+#include <sys/types.h>
+
+/*
+ * EdonR allows to call EdonRUpdate() consecutively only if the total length
+ * of stored unprocessed data and the new supplied data is less than or equal
+ * to the BLOCK_SIZE on which the compression functions operates.
+ * Otherwise an assertion failure is invoked.
+ */
+
+/* Specific algorithm definitions */
+#define	EdonR224_DIGEST_SIZE	28
+#define	EdonR224_BLOCK_SIZE	64
+#define	EdonR256_DIGEST_SIZE	32
+#define	EdonR256_BLOCK_SIZE	64
+#define	EdonR384_DIGEST_SIZE	48
+#define	EdonR384_BLOCK_SIZE	128
+#define	EdonR512_DIGEST_SIZE	64
+#define	EdonR512_BLOCK_SIZE	128
+
+#define	EdonR256_BLOCK_BITSIZE	512
+#define	EdonR512_BLOCK_BITSIZE	1024
+
+typedef struct {
+	uint32_t DoublePipe[16];
+	uint8_t LastPart[EdonR256_BLOCK_SIZE * 2];
+} EdonRData256;
+typedef struct {
+	uint64_t DoublePipe[16];
+	uint8_t LastPart[EdonR512_BLOCK_SIZE * 2];
+} EdonRData512;
+
+typedef struct {
+	size_t hashbitlen;
+
+	/* + algorithm specific parameters */
+	int unprocessed_bits;
+	uint64_t bits_processed;
+	union {
+		EdonRData256 p256[1];
+		EdonRData512 p512[1];
+	} pipe[1];
+} EdonRState;
+
+void EdonRInit(EdonRState *state, size_t hashbitlen);
+void EdonRUpdate(EdonRState *state, const uint8_t *data, size_t databitlen);
+void EdonRFinal(EdonRState *state, uint8_t *hashval);
+void EdonRHash(size_t hashbitlen, const uint8_t *data, size_t databitlen,
+    uint8_t *hashval);
+
+#endif	/* __EDONR_H__ */
--- old/usr/src/uts/common/sys/fs/zfs.h	Tue Feb 19 01:00:54 2013
+++ new/usr/src/uts/common/sys/fs/zfs.h	Tue Feb 19 01:00:54 2013
@@ -180,6 +180,7 @@
 	ZPOOL_PROP_COMMENT,
 	ZPOOL_PROP_EXPANDSZ,
 	ZPOOL_PROP_FREEING,
+	ZPOOL_PROP_DDT_SALT,
 	ZPOOL_NUM_PROPS
 } zpool_prop_t;
 
--- /dev/null	Tue Feb 19 01:00:54 2013
+++ new/usr/src/uts/intel/edonr/Makefile	Tue Feb 19 01:00:54 2013
@@ -0,0 +1,91 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2013 Saso Kiselkov.  All rights reserved.
+#
+#	This makefile drives the production of the edonr crypto kernel module.
+#	intel architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+COMDIR	= $(COMMONBASE)/crypto
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= edonr
+OBJECTS		= $(EDONR_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(EDONR_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_CRYPTO_DIR)/$(MODULE)
+ROOTLINK	= $(ROOT_MISC_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE) $(ROOTLINK)
+
+#
+# Linkage dependencies
+#
+LDFLAGS += -dy -Nmisc/kcf
+
+CFLAGS += -xO5 -_gcc=-O3
+CFLAGS64 += -xO5 -_gcc=-O3
+LINTFLAGS	+=
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+$(ROOTLINK):	$(ROOT_MISC_DIR) $(ROOTMODULE)
+	-$(RM) $@; ln $(ROOTMODULE) $@
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
--- /dev/null	Tue Feb 19 01:00:54 2013
+++ new/usr/src/uts/sparc/edonr/Makefile	Tue Feb 19 01:00:54 2013
@@ -0,0 +1,91 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2013 Saso Kiselkov.  All rights reserved.
+#
+#	This makefile drives the production of the edonr crypto kernel module.
+#	sparc architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+COMDIR	= $(COMMONBASE)/crypto
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= edonr
+OBJECTS		= $(EDONR_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(EDONR_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_CRYPTO_DIR)/$(MODULE)
+ROOTLINK	= $(ROOT_MISC_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sparc/Makefile.sparc
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE) $(ROOTLINK)
+
+#
+# Linkage dependencies
+#
+LDFLAGS += -dy -Nmisc/kcf
+
+CFLAGS += -xO5 -_gcc=-O3
+CFLAGS64 += -xO5 -_gcc=-O3
+LINTFLAGS	+=
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+$(ROOTLINK):	$(ROOT_MISC_DIR) $(ROOTMODULE)
+	-$(RM) $@; ln $(ROOTMODULE) $@
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/sparc/Makefile.targ
