<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>chacha20 &#8211; 编程技术记录</title>
	<atom:link href="https://blog.z6z8.cn/tag/chacha20/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.z6z8.cn</link>
	<description>世界你好!</description>
	<lastBuildDate>Tue, 24 Sep 2019 02:09:26 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Java：Chacha20算法（从openssl移植）</title>
		<link>https://blog.z6z8.cn/2019/09/24/java%ef%bc%9achacha20%e7%ae%97%e6%b3%95%ef%bc%88%e4%bb%8eopenssl%e7%a7%bb%e6%a4%8d%ef%bc%89/</link>
		
		<dc:creator><![CDATA[holdsky]]></dc:creator>
		<pubDate>Tue, 24 Sep 2019 02:09:26 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[chacha20]]></category>
		<category><![CDATA[java]]></category>
		<guid isPermaLink="false">http://blog.z6z8.cn/?p=406</guid>

					<description><![CDATA[使用示例 String str = "hello world"; int key[] = {-123,-456 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>使用示例</p>
<pre><code class="language-java">        String str = "hello world";

        int key[] = {-123,-456,789,123,456,7890,456,456};
        int noc[] = {-123,-456,789,123};

        byte[] encryptData = Chacha20.crytpoCounter32(str.getBytes(),key,noc);

        byte[] decryptData = Chacha20.crytpoCounter32(encryptData,key,noc);

        String str2 = new String(decryptData);

        boolean equal = str.equals(str2);</code></pre>
<p>具体代码</p>
<pre><code class="language-java">package com.zxs.zl;

/*
 * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

public class Chacha20 {
    /*
     * ChaCha20_ctr32 encrypts |len| bytes from |inp| with the given key and
     * nonce and writes the result to |out|, which may be equal to |inp|.
     * The |key| is not 32 bytes of verbatim key material though, but the
     * said material collected into 8 32-bit elements array in host byte
     * order. Same approach applies to nonce: the |counter| argument is
     * pointer to concatenated nonce and counter values collected into 4
     * 32-bit elements. This, passing crypto material collected into 32-bit
     * elements as opposite to passing verbatim byte vectors, is chosen for
     * efficiency in multi-call scenarios.
     */

    /**
     * function same  ,encrypt and decrypt
     * @param inp source data (encrypt data or decrypt data)
     * @param key int[8] array
     * @param counter int[4] array
     * @return  decrypt data or encrypt data ; see inp param.
     */
    public static byte[] crytpoCounter32(byte[] inp, int[] key,int[] counter)
    {
        byte[] out = new byte[inp.length];

        int[] input = new int[16];

        byte[] buf = new byte[64];
        int todo, i;

        /* sigma constant "expand 32-byte k" in little-endian encoding */
        input[0] = ((int)'e') | ((int)'x'&lt;&lt;8) | ((int)'p'&lt;&lt;16) | ((int)'a'&lt;&lt;24);
        input[1] = ((int)'n') | ((int)'d'&lt;&lt;8) | ((int)' '&lt;&lt;16) | ((int)'3'&lt;&lt;24);
        input[2] = ((int)'2') | ((int)'-'&lt;&lt;8) | ((int)'b'&lt;&lt;16) | ((int)'y'&lt;&lt;24);
        input[3] = ((int)'t') | ((int)'e'&lt;&lt;8) | ((int)' '&lt;&lt;16) | ((int)'k'&lt;&lt;24);

        input[4] = key[0];
        input[5] = key[1];
        input[6] = key[2];
        input[7] = key[3];
        input[8] = key[4];
        input[9] = key[5];
        input[10] = key[6];
        input[11] = key[7];

        input[12] = counter[0];
        input[13] = counter[1];
        input[14] = counter[2];
        input[15] = counter[3];

        int len = inp.length;
        int offset = 0;
        while (len &gt; 0) {
            todo = 64;// equal to buf.length;
            if (len &lt; todo)
                todo = len;

            chacha20_core(buf, input);

            for (i = 0; i &lt; todo; i++){
                out[i+offset] = (byte) (inp[i+offset] ^ buf[i]);
            }
            offset += todo;
            len -= todo;

            /*
             * Advance 32-bit counter. Note that as subroutine is so to
             * say nonce-agnostic, this limited counter width doesn't
             * prevent caller from implementing wider counter. It would
             * simply take two calls split on counter overflow...
             */
            input[12]++;
        }
        return out;
    }

    /* chacha_core performs 20 rounds of ChaCha on the input words in
     * |input| and writes the 64 output bytes to |output|. */
    private static void chacha20_core(byte[] output, int[] input)
    {
        //output byte[64]
        long[] x = new long[16];
        for (int i = 0 ; i &lt; 16 ;i++){
            x[i] = (input[i] &amp; 0xFFFFFFFFL );
        }
        for (int i = 20; i &gt; 0; i -= 2) {
            QUARTERROUND(x,0, 4, 8, 12);
            QUARTERROUND(x,1, 5, 9, 13);
            QUARTERROUND(x,2, 6, 10, 14);
            QUARTERROUND(x,3, 7, 11, 15);
            QUARTERROUND(x,0, 5, 10, 15);
            QUARTERROUND(x,1, 6, 11, 12);
            QUARTERROUND(x,2, 7, 8, 13);
            QUARTERROUND(x,3, 4, 9, 14);
        }

        for (int i = 0; i &lt; 16; ++i) {
            long v = (x[i] + input[i]) &amp; 0xFFFFFFFFL;
            output[i&lt;&lt;2] = (byte) (v &amp; 0xFF);
            output[(i&lt;&lt;2) + 1] = (byte) ((v&gt;&gt;8) &amp; 0xFF);
            output[(i&lt;&lt;2) + 2] = (byte) ((v&gt;&gt;16) &amp; 0xFF);
            output[(i&lt;&lt;2) + 3] = (byte) ((v&gt;&gt;24) &amp; 0xFF);
        }
    }

    /* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
    private static void QUARTERROUND(long[]x, int a,int b,int c,int d){
        x[a] = (x[a] + x[b]) &amp; 0xFFFFFFFFL;
        x[d] = ROTATE((x[d] ^ x[a]),16) &amp; 0xFFFFFFFFL;
        x[c] = (x[c] + x[d]) &amp; 0xFFFFFFFFL;
        x[b] = ROTATE((x[b] ^ x[c]),12) &amp; 0xFFFFFFFFL;
        x[a] = (x[a] + x[b]) &amp; 0xFFFFFFFFL;
        x[d] = ROTATE((x[d] ^ x[a]), 8) &amp; 0xFFFFFFFFL;
        x[c] = (x[c] + x[d]) &amp; 0xFFFFFFFFL;
        x[b] = ROTATE((x[b] ^ x[c]), 7) &amp; 0xFFFFFFFFL;
    }
    private static long ROTATE(long v,int n)
    {
        v = v &amp; 0xFFFFFFFFL;
        return (((v) &lt;&lt; (n)) | ((v) &gt;&gt; (32 - (n))));
    }
}</code></pre>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
